Friday, January 13, 2012

DPM 2010 - Script to export all recoverable item to drive

Ok so I finished writing my script for exporting recovery data to f: drive (local to DPM 2010 server) for all the servers (DPM 2010 Agents) I have 4 of them.
If any of you had the pleasure of doing this through GUI knows how painful it is... I fortunately was very lucky to be assigned to export (recover to network folder) 16 datasources from 4 different servers. After doing this for couple of days I started looking at cmdlets and found some scripts and hints on how to do this. and then...
This scripts loops through all the servers and all the datasource protected and recovers them to f: drive then it 7z the files and put in 7z folder it also date stamps folders and 7z files. You have to download 7za and place it in system32 folder in order for it to 7z the folders.

I am posting this script to that it might come handy to someone else out there.

I use this in production environment and it works fine but doesn’t mean it might work for you. So standard disclaimer use it at your own risk! ( I did not write some of the code and copied it from other user posts from this forum. Hopefully they won’t mind). You are free to modify and use the script.

It recovers SQL, System Protection and Exchange 2010. Please note I only export exchange recovery on 15th of every month you can change that. Search for “#Only run Exchange Recovery on 15th of every month. Otherwise Skip” and change the days below that.

# ====================================
# = DPM 2010 Recover to Drive looped =
# = for all servers and datasource.  =
# ====================================
# Created: [01/12/12]
# By EvilWasp

#0 Time Stamp folders
$date = get-date
$TimeStamp = $date.ToShortDateString()
#Replace / as folder name cannot contain it.
$time = $TimeStamp.Replace("/", "-") 
 
#1 You have to modify the below varibles to make it work for you.
#Below varibles
$DPMServerName = "Krait"
$DestinationLocation = "F:\Recovered\$time"
$Destination7z = "F:\7z\$time"
 
#2 Import DPM Shell if its not loaded.
If((Get-PSSnapIn -Name "Microsoft.DataProtectionManager.PowerShell" -ErrorAction SilentlyContinue) -eq $null)
    {
  Add-PSSnapIn "Microsoft.DataProtectionManager.PowerShell"
  Start-Sleep 5
    }

#3 Get list of DPM Agents - Protected Group
$pg = Get-ProtectionGroup -DPMServerName $DPMServerName
#Count how many servers!
$pgc = $pg.count

#4 Start Function Recover it needs $i from $pg.
Function Recover ($i)
{
  #if $i is not null then do the loop.
  If ($i -ne $null) 
  {
    $dsc = $ds.count #Counting how many datasource is available in array
    #Loop through all the servers with ForLoop
    For ($d=0; $d -le $dsc; $d++) #looping datasource for each servers
    {
    $dsn = $ds[$d]
    #8 If & ElseIf Statments to find the write command for each recovery.
    #Three different types -SQL, -SystemProtectionDataSource and -E14datasource for exchange 2010 (Use -Exchange) for older versions. 
    #There's -FileSystem as well which I havent used.
    #-like is used with wildcard(*) to accomodate different versions of SQL i.e 2005, 2008 extra.
        
        #find SQL server in each server
        If ($dsn.Type.Name -like "SQL Server*") 
            {
            #Recovery Options - Where to place recovered files - for SQL
            $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
            -SQL -RecoveryType restore
            }
        #find System Protection server
        ElseIf ($dsn.Type.Name -like "System Protection*") 
            {
            #Recovery Options - Where to place recovered files - for System Protection
            $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
            -SystemProtectionDataSource -RecoveryType restore
            }
        #find Exchange server
        ElseIf ($dsn.Type.Name -like "Exchange Mailbox Database*") 
            {
            #Only run Exchange Recovery on 15th of every month. Otherwise Skip.
            If ($date.Day -eq 15) 
                {
            #Recovery Options - Where to place recovered files - for Exchange 2010
            $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
            -E14datasource -ExchangeOperationType NoOperation -RecoveryType restore
                }
                #If its not the 15th of month then skip
                Else
                {
                Continue
                }
            }
        #If $dsn.Type.Name is nothing/null skip
        Else
         {
         Continue
         }
        #Sort by latest on top Recovery Points.
        $recoveryPoints = @(Get-RecoveryPoint -datasource $dsn | sort -property RepresentedPointInTime -Descending)
            If ($recoveryPoints.Length -eq 0)
                {
                 Write-Host "No recovery point available for" $dsn.Name -ForeGroundColor Yellow
                 }
            Else
                {
        #Select the latest recovery point found on Array [0]
        $latestRecoveryPoint = $RecoveryPoints[0]
        #Recovering
        Write-Host "Recovering" $dsn.Name
        #Run Recovery Job
        $recoveryJob = Recover-RecoverableItem -RecoverableItem $latestRecoveryPoint -RecoveryOption $rop -JobStateChangedEventHandler $jobStateChangeHandler
                }
        #If it failed!
        If(!$recoveryJob)
            {
        Write-Host "Failure on invoking Recover-RecoverableItem" -ForeGroundColor Red
        Continue
            }        
        #Wait till the recovery job completes
        while (! $recoveryJob.hasCompleted )
        { 
        # Show a progress bar
        Write-Host "." -NoNewLine
        Start-Sleep 5
        }
        if($recoveryJob.Status -ne "Succeeded")
        {
        Write-Host "Recovery failed" -ForeGroundColor Red
        }
        else
        {
        Write-Host "Recovery successful" -ForeGroundColor Green
        }
    
    }
  }    
}
#End Function

#5 Count Servers in $pg array
for ($i=0; $i -le $pgc; $i++)
{
#Selecting server and displaying datasource
$ds = Get-Datasource $pg[$i] 
#Call Recover function with $i (server) from #5
Recover $i
}

#6 Once all of recovery is exported 7z these.
cd\ #Ensure its on root
cd $DestinationLocation
$dir = pwd
If ($dir.path -eq  $DestinationLocation)
    {
#7 "&" is required before calling external file.
#Call 7za.exe to compress the whole folder. 7za command line tool needs to be downloaded and placed in system32 folder b4 hand
Write-host "Starting compressiong phase. At $date ....."
Write-host "Compressing Recovered files from DPM Server. This will take time!" -ForeGroundColor Green
& 7za a -t7z "$Destination7z DPM.7z" * 
Write-host "Compression done At $date"    
    }
Else 
    {
Write-host "Something went wrong. You have to run 7z manually!"  -ForeGroundColor Red
    }
#All done exit
Exit
 
 
You can download the ps1 version from Google Docs here's the link.

4 comments:

  1. Hello,

    I've been working with this script for a few months now, but sadly I haven't been able to get it to work. I've been attempting to expand it to also recover file shares and Sharepoint. The snippet ends up looking like this:

    #find file shares in each server
    If ($dsn.Type.Name -like "file share*")
    {
    #Recovery Options - Where to place recovered files - for file shares
    $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
    -fileshares -RecoveryType restore
    }
    #find Sharepoint in each server
    If ($dsn.Type.Name -like "Sharepoint*")
    {
    #Recovery Options - Where to place recovered files - for Sharepoint
    $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
    -Sharepoint -RecoveryType restore
    }
    #find SQL instance in each server
    If ($dsn.Type.Name -like "SQL Server*")
    {
    #Recovery Options - Where to place recovered files - for SQL
    $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
    -SQL -RecoveryType restore
    }
    #find System Protection server
    ElseIf ($dsn.Type.Name -like "System Protection*")
    {
    #Recovery Options - Where to place recovered files - for System Protection
    $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
    -SystemProtection -RecoveryType restore
    }
    #find Exchange server
    ElseIf ($dsn.Type.Name -like "Exchange*")
    {
    #Recovery Options - Where to place recovered files - for Exchange 2010
    $rop = New-RecoveryOption -TargetServer $DPMServerName -TargetLocation $DestinationLocation -RecoveryLocation CopyToFolder `
    -Exchange -ExchangeOperationType NoOperation -RecoveryType restore
    }

    but it only finds Exchange and Project Server. Are my naming conventions bad? I'm trying very hard to avoid buying Firestreamer for $1300. You're my only hope, ijaved! :)

    ReplyDelete
    Replies
    1. PG Aerotech I am very sorry I have been away from the post. I hope you managed to troubleshoot the issue. What I usually do in such cases is that I try to run the command one by one through Powershell ISE and it helps me nail down the issue where it is being broken. I know its probably too late but hopefully it will help yo in feature.

      Delete
  2. Great work!

    I've made few corrections for dpm 2012r2 but main part is still operational.

    Thanks a lot!

    ReplyDelete
    Replies
    1. Thanks River-Fall. Would love to see the modification. Sorry I have been away from the site for awhile. I will be playing with DPM 2012r2 too very soon. So your modification might come handy.

      Delete