Recover-Recoverable Item - System Center: Data Protection Manager Engineering Team Blog - Site Home - TechNet Blogs

Recover-Recoverable Item

Recover-Recoverable Item

  • Comments 4
  • Likes

Its 6:00PM.  You were supposed to leave at 5:00PM.  Your boss catches you as you walk out the door and says he needs a file restored for a presentation first thing in the morning.  You say, “No problem, I will restore it real quick before I head home.”  You head to the DPM server and try and open the console.  To your dismay, the console will not open.  You inform your boss of the situation.  He asks if there is any way at all to restore the file because he cannot wait until the morning.  You remember that when you installed DPM that it required PowerShell.  Maybe there is a way to restore files from the DPM Management Shell?  You are exactly right!  But you have never done it.

This blog will walk you through the steps of doing a simple file restore from Powershell.

From previous blogs you learned some of the fundamentals of Powershell; specifically arrays and index values.  In this PowerShell cmdlet you will put that knowledge to the test.

This is the command as listed in Technet:

Recover-RecoverableItem [-RecoverableItem] <RecoverableObject[]> [-RecoveryOption] <RecoveryOptions> [-RecoveryPointLocation <RecoverySourceLocation[]>] [-JobStateChangedEventHandler <JobStateChangedEventHandler>] [-RecoveryNotification <Nullable`1>] [-Verbose] [-Debug] [-ErrorAction <ActionPreference>] [-ErrorVariable <String>] [-OutVariable <String>] [-OutBuffer <Int32>]

 

Looks too difficult to attempt at 6:15PM right?  Wife is waiting for you to eat dinner, kids need their baths, etc… Sound familiar?

Let’s simply this cmdlet; you will need some information to do the recovery.

What you will need:

1.       Recoverable Object

2.       Recovery Options

3.       Recovery Point Location

First we need to get a recoverable object. Easy enough right?  Wrong, it requires three variables and those have to be indexed into the get-recoverypoint cmdlet so technically you get two cmdlets for the price of one in this blog.

You will be creating three variables

1.       $pg = get-protectiongroup –dpmservername dpmserver1

a.       This will return an array; assign an index value to the first one you see as 0, the second one will be 1, etc…clip_image002

2.       $ds = get-datasource –protectiongroup[$pg_arrayindexvaluefromabove]

a.       This will return an array

clip_image004

3.       $rp= get-recoverypoint –datasource[$ds_arrayindexvalue]

clip_image006

4.       $gr = get-recoverableitem –recoverableitem $rp[0]

clip_image008

Once you have the above three variables created you can now determine which recovery point you want to restore.  No, we are not done yet but we now have most of the information necessary to perform the recovery.  Just a few more variables and we are done.

Let’s look at recover-recoverableitem again.  This time we will look at the bare minimum that you will need to get your bosses file restored so you can get out the door to go home.

Recover-RecoverableItem [-RecoverableItem] <RecoverableObject[]> [-RecoveryOption] <RecoveryOptions> [-RecoveryPointLocation <RecoverySourceLocation[]>]

 

Recover-recoverableitem requires 3 pieces of information.  We have the recoverable object in the array index value from $rp above.

We also need recovery options ($rop.)  This is another variable.  It takes information that you input and when the item is recovered, it uses these variables to overwrite the file, restore the file, etc…

 $rop

Once we have the $rop variable we can finally restore the file.

Captureend

You can see from the above screenshot that we are now in progress of putting the file back where it came from.

Walt Whitman

Support Escalation Engineer

Microsoft System Center Support

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • I have to say that compared to Exchange, DPM's PowerShell cmdlets are poorly documented and implemented. For instance, Get-ProtectionGroup can’t get you a protection group. It only gets you all of the protection groups. It should be called Get-ProtectionGroups.

    I should be able to get protection groups, data sources, etc. by name like the following (as you can get databases in Exchange):

    Get-ProtectionGroup “backupServer\Protection Group”

    instead of running a command, counting and referencing an index number or doing something ugly like:

    $pg = Get-ProtectionGroup -DPMServerName backupServer | Where-Object {$_.FriendlyName -eq "Protection Group"}

    (It’s also annoying that in the table output of $pg, the header is Name, but the property is actually FriendlyName – those things should be consistent so I don’t have to run get-member all the time.)

    This post also didn't go into restoring a particular file that's nested deeply. As far as I can tell, you either have to use Get-RecoverableItem -searchoption which is slow or navigate down using something like:

    $SubFolder1 = Get-RecoverableItem -RecoverableItem $rp -BrowseType child | Where-Object {$_.Filename -eq "SubFolder1"}

    $SubFolder2 = Get-RecoverableItem -RecoverableItem $SubFolder1 -BrowseType child | Where-Object {$_.Filename -eq "SubFolder2"}

    Once I have a recovery point, I should be able to pass the path of the file or folder I need to restore directly instead of the nonsense above.

  • Why didn't the console open in the first place? This confirms my experience that the console performs poorly and that it is not possible to have two administrators use the console the same time.

  • I’ve got what I thought would be a simple task with Data Protection Manager 2010 that is turning out to be quite frustrating. I have a file server on one server and it is the only server in a protection group. This file server is the repository for a document management application which stores the files according to the data within a SQL database. Sometimes users inadvertently delete files from within our application and we need to restore them. We have all the information needed to restore the files to include the file name, the folder that the file was stored in and the exact date that the file was deleted. It is easy for me to restore the file from within the DPM console since we have a recovery point created every day, I simply go to the day before the delete, browse to the proper folder and restore the file. The problem is that using the DPM console, the cumbersome wizard requires about 20 mouse clicks to restore a single file and it takes 2-4 minutes to get through all the windows. This becomes very irritating when a client needs 100’s of files restored… it takes all day of redundant mouse clicks to restore the files.

    Therefore, I want to use a PowerShell script (and I’m a novice at PowerShell) to automate this process. I want to be able to create a script that I pass in a file name, a folder, a recovery point date (and a protection group/server name if needed) and simply have the file restored back to its original location with some sort of success/failure notification. I thought it was a simple basic task of a backup solution, but I am having a heck of a time finding the right code.

    I have tried to use the sample code above, but it doesn’t accomplish what I really want to do (it’s too simplistic and not capable of being automated with the known values of the file to restore) and there are errors in the sample code. Therefore, I would like to get some help writing a script to restore these files.

    An example of the known values to restore the data are:

      DPM Server: BACKUP01

      Protection Group: Document Repository Data

      Protected Server: FILER01

      File Path: R:\DocumentRepository\ToBackup\ClientName\Repository\2010\07\24\filename.pdf

      Date Deleted: 8/2/2010 (last recovery point = 8/1/2010, exact time unknown though)

    Bonus Points:

    If you can help me not only create this script, but also show me how to automate by providing a text file with the above information that the PowerShell script loops through, or even better, is able to query our SQL server for the needed data, then I would be more than willing to pay for this development.

    You can reach me at brian-at-mccleary-dot-com

  • Well, after much frustration and research, I have come up with a working script.  For those that want to know how to do the same, the script below works well to restore any given file.

       <#

       Parameters: Folder Path, File to Restore, Deletion Date

       Example Usage:

       .\RecoverFile.ps1 "ClientName\Folder\2010\02\03\" "mydoc.pdf" "2010-08-04 09:54:24.117"

       #>

       $filePath = [IO.Path]::Combine("D:\ClientData\", $args[0] )

       $fileName = $args[1]

       $dateDeleted = Get-Date $args[2]

       Write-Host "Restoring '" -NoNewLine

       Write-Host $filePath -NoNewLine

       Write-Host $fileName -NoNewLine

       Write-Host "' which was deleted on '" -NoNewLine

       Write-Host $dateDeleted -NoNewLine

       Write-Host "'"

       $recoveryDate = Get-Date $dateDeleted.AddDays(-1).ToShortDateString()

       $pg = Get-ProtectionGroup -DPMServerName DPMSERVER01 | Where-Object {$_.FriendlyName -eq "Document Repository Data"}

       $ds = Get-Datasource $pg

       $so = New-SearchOption -FromRecoveryPoint $recoveryDate.AddDays(-1).ToShortDateString() -ToRecoveryPoint $recoveryDate.ToShortDateString() -SearchDetail FilesFolders -SearchType exactMatch -Location $filePath -SearchString $fileName

       $ri = Get-RecoverableItem -Datasource $ds -SearchOption $so

       $ro = New-RecoveryOption -TargetServer CLIENTDATASERVER01 -RecoveryLocation OriginalServer -FileSystem -OverwriteType overwrite -RecoveryType Recover

       $recoveryJob = Recover-RecoverableItem -RecoverableItem $ri -RecoveryOption $ro

       #4.3 Wait till the recovery job completes

       while (! $recoveryJob.hasCompleted )

       {

           # Show a progress bar

           Write-Host "." -NoNewLine

           Start-Sleep 1

       }

       if($recoveryJob.Status -ne "Succeeded")

       {

           Write-Host "Recovery failed" -ForeGroundColor Red

       }

       else

       {

           Write-Host "Recovery successful" -ForeGroundColor Green

       }