Snapshots and SharePoint 2010 are a great thing in that they provide an additional level of fault tolerance for any SharePoint 2010 farm.  A SharePoint Administrator can quickly restore Sites, Lists, or items from a snapshot.   This out of the box solution is possible through the Central Administrators Recover Data from an unattached content database feature.   This functionality exports the user selected data out of the Snapshot database and into a backup file.  Finally, the backup file and be used with import-spweb to restore the data.  For a walkthrough of restoring snapshots using Central Administrator,  see my blog posts here

I recently found out this functionality isn’t possible using out of the box PowerShell cmdlets.   I put together a PowerShell script that will guide you through Recovering Data from an Unattached database.   It’s possible to recover from a Site, Subsite, List, or Document Library.  Once, the export is complete, simply run import-spweb cmdlet.   I recommend running this in a test farm to get more familiar with it.  

In order to run this, save the below script to a text editor like notepad.   Save the file with a .ps1 extension.   To run the file from PowerShell, run .\yourfilename.ps1

I assume you know the following things when running this script:

 

1.  If the end goal is restoring a specific subsite, it’s expected that you know the partial path to your subsite. 

For Example:   Site Collection is:  http://contoso

Let’s assume subsite1 is a subsite that resides directly under contoso and subsite2 is a subsite that resides directly under SubSite1.

The full url looks like:   http://contoso/subsite1/subsite2

    • To restore subsite1, the partial url is:  /subsite1
    • To restore subsite2, the partial url is: /subsite1/subsite2

 

2.  It’s expected that you know the list or document library name.  

3.  It’s assumed that your Central Admin site’s display name contains the words “Central Admin”, if this isn’t the case, adjust the $_.DisplayName property on the line which declares $caweb variable.

 

Enjoy!

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
Add-PSSnapin Microsoft.SharePoint.PowerShell

Start-SPAssignment -Global
Write-Host "This PowerShell script will assists you in exporting data out of a snapshot and into a physical file which can then be restored via import-spweb."  
Write-Host "  "

####################
#    Initial Setup #
####################

#Get the CA URL
$caweb = Get-SPWebapplication -IncludeCentralAdministration | where{$_.DisplayName -match "Central Admin"}
$ca = $caweb.url

##############################
#Manually Grab other settings#
##############################
$SQLserv = Read-Host "Enter your SQL Server Name"
$location = Read-Host "Enter desired backup directory (For Example: D:\backupdir)"
$filename = Read-Host "Enter desired backup filename  (For Example: bufile.cmp)"
$includesec = Read-Host "Press y to include security or any other key to export without security"

##################################################
#Choose a ContentDB and inserting into $contentDB#
##################################################
$cdb = Get-SPContentDatabase 
$cdbname = $cdb | ForEach-Object {$_.Name}
Write-Host
write-host "Choose a Content Database from which the snapshot was taken"
Write-Host
$num = 0

Foreach ($i in $cdbname)
{
    Write-Host $num $i
    $num++
}

$result = Read-Host
$num = 0
Foreach($i in $cdbname)
{
   if($num -eq $result)
   {
       $contentDB = $i
   }
   $num++
}
  

###############################################  
#Select a snapshot and inserting it in $snapdb#
###############################################
$snapdbs = Get-SPContentDatabase $contentDB
$snap = $snapdbs.Snapshots | ForEach-Object {$_.Name}
$num = 0
Write-Host
Write-Host "Select a Snapshot"
Foreach ($i in $snap)
{
    Write-Host $num $i
    $num++
}
$num = 0

$result = Read-Host
Foreach($i in $snap)
{
   if($num -eq $result)
   {
       $snapdb = $i
   }
   $num++
}

#####################
# Grab the Snapshot #
#####################
$snapshot = [Microsoft.SharePoint.Administration.SPContentDatabase]::CreateUnattachedContentDatabase($SQLserv, $snapdb, $null, $null)


################
#Choose a site #
################
$snapnames = $snapshot.Sites | ForEach-Object {$_.Url}
Write-Host
Write-Host "Choose a site to export from"
$num = 0
ForEach($i in $snapnames)
{
    write-host $num $i
    $num++
}
$result = Read-Host
$num = 0
ForEach($i in $snapnames)
{
     if($num -eq $result)
    {
        $URL = $i
    }
    $num++
}

Write-Host "You chose site"
Write-Host $URL


##############################
#Only export from a subsite? #
##############################
write-host "Press y to export from a specific subsite"
write-host "Press any other key to export from the site collection level"
$subdec = Read-Host
if(($subdec -eq "Y") -or ($subdec -eq "y"))
{
        write-host "Please Enter the subsite name in the format of /subsitename"
        write-host "For Example:
http://contoso/subsite1 would look like /subsite1"
        $subsite = Read-Host
        $URL2 = $URL + $subsite
}

###############################
#Only export a list or doclib?#
###############################
Write-host "Press y to only export a list or document library"
Write-Host "Press any other key to export from site level"
$listit = Read-Host
if(($listit -eq "y") -or ($listit -eq "Y"))
{
    Write-Host "Please enter the list or doc library in the format of /testlist"
    Write-Host "For Example:
http://contoso/testlist would look like: /testlist"
    $list = Read-Host
    if(($subdec -eq "Y") -or ($subdec -eq "y"))
    {
        $URL2 = $URL2 + $list
    }
    elseif(($subdec -ne "Y") -or ($subdec -ne "y"))
    {
        $URL2 = $URL + $list
    }
}

#####################################
#  Inserting Site or List to export #
#####################################
$exportobject = New-Object Microsoft.SharePoint.Deployment.SPExportObject

if(($listit -ne "y") -or ($listit -ne "Y"))
{
    $exportobject.Type = [Microsoft.SharePoint.Deployment.SPDeploymentObjectType]::Web
    if(($subdec -eq "Y") -or ($subdec -eq "y"))
    {
        $exportobject.Url = $URL2
    }
    else {$exportobject.Url = $URL}
}

elseif(($listit -eq "y") -or ($listit -eq "Y"))
{
    $exportobject.Type = [Microsoft.SharePoint.Deployment.SPDeploymentObjectType]::List
    $exportobject.Url = $URL2
}

$exportobject.IncludeDescendants = [Microsoft.SharePoint.Deployment.SPIncludeDescendants]::All


##############################
# Configuring Export Settings#
##############################
$exportsettings = New-Object Microsoft.SharePoint.Deployment.SPExportSettings
$exportsettings.UnattachedContentDatabase = $snapshot
$exportsettings.SiteURL = $URL
$exportsettings.FileLocation = $location
$exportsettings.LogFilePath = $location
$exportsettings.BaseFileName = $filename
$exportsettings.ExportObjects.Add($exportobject)
$exportsettings.IncludeVersions = [Microsoft.SharePoint.Deployment.SPIncludeVersions]::All
$exportsettings.LogExportObjectsTable = 1

if($includesec -eq "y" -or "Y")
{
  $exportsettings.IncludeSecurity = [Microsoft.SharePoint.Deployment.SPIncludeSecurity]::All
}

####################################
#  Create Export Object and Export #
####################################
$export = New-Object Microsoft.SharePoint.Deployment.SPExport($exportsettings)
Write-Host
Write-Host "Starting Export"
$export.Run()
Write-Host
Write-Host "Operation Completed Successfully!"


Stop-SPAssignment –Global

 

Thanks!

Russ Maxwell, MSFT   Alien