I have been working in IT since 2001 for companies such as Computacenter and Getronics. I started out as a first line support analyst supporting heterogeneous networks but rapidly worked my way up the ranks expanding my knowledge as I went to include areas such as system builds, deployments, networking, and security to name a few.In 2008 I decided to concentrate on the monitoring and management of large enterprise networks using Microsoft's System Center Operations Manager (OpsMgr) 2007 of which I have extensive knowledge. As testament to this the Windows Management User Group (WMUG), invited me to join their ranks as a Community Leader where I have been invaluable in helping to bolster the OpsMgr skills to the benefit of the group and it's members.I have now moved into an OpsMgr 2007 consultancy role to do what I like most - working with OpsMgr and sharing my knowledge and experiences with the community.
As there is no central console for managing multiple Data Protection Manager servers, I like to use PowerShell wherever possible when performing DPM tasks. Recently I had the need to restore a share so what better time to write another script. :-)
There is a good script at http://gallery.technet.microsoft.com/ScriptCenter/en-us/68f52621-2086-40ed-905b-60c9eabe6337 which will restore all shares and volumes within a protection group to a network share but what if you want to just recover a single share. To do this you need to make use of the RecoveryPointForShares parameter with the Get-RecoverableItem cmdlet which at the time of writing this was not documented on the Microsoft DPM Management Shell Technical Reference library.
So, here is an example script on how to restore a specific share. This will also be posted on the script repository.
param([string] $DPMServerName, $ProtectionGroup, $Datasource, $ShareName, $DestinationServer, $DestinationLocation) function Usage() { write-host write-host "Usage::" write-host "Recover-Share.ps1 -DPMServerName [DPMServerName] -ProtectionGroup [ProtectionGroupName] -Datasource [DatasourceName] -ShareName [ShareName] -DestinationServer [DestinationServer] -DestinationLocation [DestinationLocation]" write-host write-host "Run 'Recover-Share.ps1 -detailed' for detailed help" write-host write-host } if(("-?","-help") -contains $args[0]) { Usage exit 0 } if(("-detailed") -contains $args[0]) { write-host write-host "Detailed Help : Use this script to recover a share" write-host write-host "Example: Recover-Share.ps1 -DPMServerName 'DPM01.lab.com' -ProtectionGroup 'Shares' -Datasource 'C:\' -ShareName 'NewShare' -DestinationServer 'FILE01.lab.com' -DestinationLocation 'C:\ShareRecovery'" write-host exit 0 } if((Get-PSSnapIn -Name "Microsoft.DataProtectionManager.PowerShell" -ErrorAction SilentlyContinue) -eq $null) { Add-PSSnapIn "Microsoft.DataProtectionManager.PowerShell" } if(!$DPMServerName) { $DPMServerName = read-host "DPMServerName::" } $DpmServer = Connect-DPMServer $DPMServerName if (!$DpmServer) { write-Error "Failed To Connect To DPM Server::$DPMServerName" exit 1 } if(!$ProtectionGroup) { $ProtectionGroup = read-host "ProtectionGroupName::" } $pg = Get-ProtectionGroup -DPMServerName $DPMServerName | where { $_.FriendlyName -eq $ProtectionGroup } if (!$pg) { write-Error "Failed To Find A Protection Group Named::$ProtectionGroup" exit 1 } if(!$Datasource) { $Datasource = read-host "DataSourceName::" } $ds = Get-Datasource $pg | where { $_.Name -eq $Datasource } if (!$pg) { write-Error "Datasource Not Found With Name::$Datasource" exit 1 } $rp = (Get-RecoveryPoint $ds | sort -Property RepresentedPointInTIme -Descending)[0] if(!$rp) { Write-Error "No Recovery Points Found For Datasource::$Datasource" exit 1 } if(!$ShareName) { $ShareName = read-host "ShareName::" } $ri = Get-RecoverableItem -RecoveryPointForShares $rp | where { $_.UserFriendlyName -eq $ShareName } if(!$ri) { Write-Error "No Recoverable Item Found For Share::$ShareName" exit 1 } if(!$DestinationServer) { $DestinationServer = read-host "DestinationServer::" } if(!$DestinationLocation) { $DestinationLocation = read-host "DestinationLocation::" } $ro = New-RecoveryOption -TargetServer $DestinationServer -RecoveryLocation copytofolder -FileSystem -AlternateLocation $DestinationLocation -OverwriteType overwrite -RestoreSecurity -RecoveryType Restore $Recovery = Recover-RecoverableItem -RecoverableItem $ri -RecoveryOption $ro if($Recovery) { Write-Host "Running recovery for $ShareName from $($rp.RepresentedPointInTime)" While(!$Recovery.HasCompleted) { Write-Host "." -NoNewLine sleep 3 } Write-Host "`nJob status: $($Recovery.Status)" } else { Write-Error "`nCould not find a recovery item on disk for $ShareName" } Disconnect-DPMServer
param([string] $DPMServerName, $ProtectionGroup, $Datasource, $ShareName, $DestinationServer, $DestinationLocation)
function Usage() { write-host write-host "Usage::" write-host "Recover-Share.ps1 -DPMServerName [DPMServerName] -ProtectionGroup [ProtectionGroupName] -Datasource [DatasourceName] -ShareName [ShareName] -DestinationServer [DestinationServer] -DestinationLocation [DestinationLocation]" write-host write-host "Run 'Recover-Share.ps1 -detailed' for detailed help" write-host write-host }
if(("-?","-help") -contains $args[0]) { Usage exit 0 }
if(("-detailed") -contains $args[0]) { write-host write-host "Detailed Help : Use this script to recover a share" write-host write-host "Example: Recover-Share.ps1 -DPMServerName 'DPM01.lab.com' -ProtectionGroup 'Shares' -Datasource 'C:\' -ShareName 'NewShare' -DestinationServer 'FILE01.lab.com' -DestinationLocation 'C:\ShareRecovery'" write-host exit 0 }
if(!$DPMServerName) { $DPMServerName = read-host "DPMServerName::" }
$DpmServer = Connect-DPMServer $DPMServerName if (!$DpmServer) { write-Error "Failed To Connect To DPM Server::$DPMServerName" exit 1 }
if(!$ProtectionGroup) { $ProtectionGroup = read-host "ProtectionGroupName::" }
$pg = Get-ProtectionGroup -DPMServerName $DPMServerName | where { $_.FriendlyName -eq $ProtectionGroup } if (!$pg) { write-Error "Failed To Find A Protection Group Named::$ProtectionGroup" exit 1 }
if(!$Datasource) { $Datasource = read-host "DataSourceName::" }
$ds = Get-Datasource $pg | where { $_.Name -eq $Datasource } if (!$pg) { write-Error "Datasource Not Found With Name::$Datasource" exit 1 }
$rp = (Get-RecoveryPoint $ds | sort -Property RepresentedPointInTIme -Descending)[0] if(!$rp) { Write-Error "No Recovery Points Found For Datasource::$Datasource" exit 1 }
if(!$ShareName) { $ShareName = read-host "ShareName::" }
$ri = Get-RecoverableItem -RecoveryPointForShares $rp | where { $_.UserFriendlyName -eq $ShareName } if(!$ri) { Write-Error "No Recoverable Item Found For Share::$ShareName" exit 1 }
if(!$DestinationServer) { $DestinationServer = read-host "DestinationServer::" }
if(!$DestinationLocation) { $DestinationLocation = read-host "DestinationLocation::" }
$ro = New-RecoveryOption -TargetServer $DestinationServer -RecoveryLocation copytofolder -FileSystem -AlternateLocation $DestinationLocation -OverwriteType overwrite -RestoreSecurity -RecoveryType Restore
$Recovery = Recover-RecoverableItem -RecoverableItem $ri -RecoveryOption $ro
if($Recovery) { Write-Host "Running recovery for $ShareName from $($rp.RepresentedPointInTime)"
While(!$Recovery.HasCompleted) { Write-Host "." -NoNewLine sleep 3 }
Write-Host "`nJob status: $($Recovery.Status)" } else { Write-Error "`nCould not find a recovery item on disk for $ShareName" }
Disconnect-DPMServer
You can download the script by clicking here: Recover-Share.zip
Basically, take the text above and paste it into Notepad and then save it as Recover-Share.ps1. Run "Recover-Share.ps1 -Detailed" in a PowerShell or DPM Management Shell window for instructions on what data you need to pass and run "Recover-Share.ps1 -?" for general help. Alternatively you can just run "Recover-Share.ps1" and provide the relevant information when prompted. If running in a normal PowerShell window (not the DPM Management Shell) you will need to make sure you are running PowerShell as an administrator otherwise the DPM snap-in will not be able to load.
Here is a little video I put together using this script.
Hope it proves helpful..... Enjoy !