Retrieving a lost document in SharePoint is easy. You go to the recycle bin and you restore it. That is, if it hasn’t been deleted more than 60 days ago. But what do you do when you need to retrieve a specific document which has been overwritten with an older version and yes, Murphy is in town… you don’t have versioning enabled?
In that case you better be having backups of the content database which contains the site where the document is stored because you need to retrieve the document directly from a backup of the content database.
Now, restoring a backup of a content database is probably not something you want to do to get a specific document because you will restore all sites in that content database to a previous state. 1 happy user vs. hundreds of angry ones… ouch! But if you don’t restore it, how are you going to get a good copy of the document?
Well, you need to restore the content database under a different name. Once it has been restored, you can use PowerShell to access it as an “unattached content database” where you can access the content as if it was attached to your web application.
The Get-SPContentDatabase cmdlet has a -ConnectAsUnattachedDatabase parameter which gives you a reference to an unattached content database.
$db = Get-SPContentDatabase -ConnectAsUnattachedDatabase -DatabaseServer SHPDB -DatabaseName "SHP_PRD_Content_MySite_RestoredCopy"
Once you have the database reference, you can use the Get-SPSite cmdlet to get your site reference from that database.
$site = Get-SPSite -ContentDatabase $db | ? {$_.Url -eq $SiteURL}
From there on, you need the web and the list where the document is stored and offcourse, the document name. With all of this information, you can get a reference to the document item in the database. Only thing left to do is to extract this item as a document.
$binary = $item.File.OpenBinary() $stream = New-Object System.IO.FileStream(($SaveLocation + $DocName), [System.IO.FileMode]::Create) $writer = New-Object System.IO.BinaryWriter($stream) $writer.Write($binary) $writer.Close() Write-Host -ForegroundColor DarkGreen "Document succesfully retrieved and saved under $SaveLocation$DocName"
I combined everything into one convenient script which takes a number of parameters and get you the item from the database.
<# .SYNOPSIS Retrieve a document from an unattached content database. .DESCRIPTION Retrieve a document from an unattached content database. .NOTES File Name: Get-DocFromUnattachedContentDB.ps1 Author : Bart Kuppens Version : 1.1 .PARAMETER DBServer Specifies the database server where the content database is located. .PARAMETER DBName Specifies the name of the content database. .PARAMETER SiteURL Specifies the URL of the site collection where the document is located. .PARAMETER WebURL Specifies the URL of the web where the document is located. Leave empty if the web is the root site of the site collection. .PARAMETER ListTitle Specifies the title of the list where the document is located. .PARAMETER DocName Specifies the name of the document. .PARAMETER SaveLocation Specifies the location where the document needs to be saved. .EXAMPLE PS > .\Get-DocFromUnattachedContentDB.ps1 -DBServer SHPDB -DBName "SHP_Temp_Mysite" -SiteURL "http://HDVWSVVS03:26100/personal/mysite" -ListTitle "Documents" -DocName "MyDoc.pptx" -SaveLocation "c:\temp\" #> [CmdletBinding()] param( [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the database server where the content database is located.")] [string]$DBServer, [parameter(Position=1,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the name of the content database.")] [string]$DBName, [parameter(Position=2,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the URL of the site collection where the document is located.")] [string]$SiteURL, [parameter(Position=3,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the URL of the web where the document is located.")] [string]$WebURL, [parameter(Position=4,Mandatory=$false,ValueFromPipeline=$false,HelpMessage="Specifies the title of the list where the document is located.")] [string]$ListTitle, [parameter(Position=5,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the name of the document.")] [string]$DocName, [parameter(Position=6,Mandatory=$true,ValueFromPipeline=$false,HelpMessage="Specifies the location where the document needs to be saved.")] [string]$SaveLocation ) if ((Get-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue) -eq $null) { Write-Host "Loading SharePoint cmdlets..." Add-PSSnapin Microsoft.SharePoint.PowerShell } # Connect to the unattached content database $db = Get-SPContentDatabase -ConnectAsUnattachedDatabase -DatabaseServer $DBServer -DatabaseName $DBName # Get a reference to the site in the DB where the document is stored $site = Get-SPSite -ContentDatabase $db | ? {$_.Url -eq $SiteURL} if ($site -eq $null) { Write-Host -ForegroundColor Red "Site $SiteURL was not found in the database" break } # Get a reference to the web in the site where the document is stored if ($WebURL -eq $null) { # WebUrl parameter was empty. The document will be on the rootweb of the site collection. $web = $site.RootWeb } else { $web = $site.AllWebs | ? {$_.Url -eq $WebURL} if ($web -eq $null) { Write-Host -ForegroundColor Red "Web $WebURL was not found in the database" break } } # Get the list where the document is stored $list = $web.Lists[$ListTitle] if ($list -eq $null) { Write-Host -ForegroundColor Red "List $ListTitle was not found on the web $webURL" break } # Get the document from the list $item = $list.Items | ? {$_.Name -eq $DocName} if ($item -eq $null) { Write-Host -ForegroundColor Red "A document with the name $DocName was not found in the $ListTitle list" break } # Extract the actual document and save it to disk $binary = $item.File.OpenBinary() $stream = New-Object System.IO.FileStream(($SaveLocation + $DocName), [System.IO.FileMode]::Create) $writer = New-Object System.IO.BinaryWriter($stream) $writer.Write($binary) $writer.Close() Write-Host -ForegroundColor DarkGreen "Document succesfully retrieved and saved under $SaveLocation$DocName"