PowerShell script exchange
Post Reply
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Hi All,

Can anyone help?

I'm trying to have a script run file-level restore tests from multiple jobs, which i have managed to do by naming each server in the script but now id like to pass it a text file with all the jobs listed in plain text.

This is what i have so far used in various other scripts and my original script where I named each server,

this isn't working though, can anyone help?

SCRIPT

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue


#Get Content from Text File
$file= Get-Content 'jobs.txt'
$jobs = Get-VBRBackup | Get-VBRRestorePoint

# Loads the latest restore point for the server
$jobs = Get-VBRBackup | Get-VBRRestorePoint 
$restore = Start-VBRWindowsFileRestore

foreach($job in $file){
   
    $vbrJob = $jobs | sort CreationTime -Descending | where {$_.Name -eq "$"} | select -First 1
    $vbrJob.Name
        }


#Targeted File or Folder
$originalFiles = "C:\test"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\test\$job"

# Copies the Files
foreach ($file in $originalFiles) {
 
   # Find the FLR mount point for the specific drive letter
  $flrmountpoint = ($restore.MountSesion.MountedDevices | ? {$_.DriveLeter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
  $file = $flrmountpoint + (Split-Path $file -NoQualifier)

  #Copy/Restore the files
 Copy-Item $file $destPath -Force -recurse
 }

# Stop the FLR process
Stop-VBRWindowsFileRestore $restore
Text File Example
Job1
Job2


I'm obviously missing something as I get the below error

cmdlet Start-VBRWindowsFileRestore at command pipeline position 1
Supply values for the following parameters:
RestorePoint:


Can anyone please help
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by Mildur »

Hi Wesley

You start the file restore session with this line. But you do not provide from which restore point.

Code: Select all

$restore = Start-VBRWindowsFileRestore
Change the order of the tasks in your script. First you have to get the restore point from the right job, then start the file level restore session with Start-VBRWindowsFileRestore. Currently, your script tries to start the restore session before you getting the restore points from the required job.

Thanks
Fabian
Product Management Analyst @ Veeam Software
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Thanks for the advice, made changes to the order but still doesn't seem correct .. what am i missing here?

Does it appear it is not seeing the restore point number requested?


cmdlet Start-VBRWindowsFileRestore at command pipeline position 1
Supply values for the following parameters:
RestorePoint:


SCRIPT

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue


#Get Content from Text File
$file = Get-Content jobs.txt
$jobs = Get-VBRBackup | Get-VBRRestorePoint
 


foreach($job in $file){
  # Matching up job name to Backup Job
$vbrjobs = $jobs | sort CreationTime -Descending | where {$_.Name -eq "$job"} | select -First 1
Start-VBRWindowsFileRestore
}

#Targeted File or Folder
$originalFiles = "C:\Windows\twain_32"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\test\"

# Copies the Files
foreach ($file in $originalFiles) {
 
   # Find the FLR mount point for the specific drive letter
  $flrmountpoint = ($restore.MountSesion.MountedDevices | ? {$_.DriveLeter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
  $file = $flrmountpoint + (Split-Path $file -NoQualifier)

  #Copy/Restore the files
 Copy-Item $file $destPath -Force -recurse
 }

# Stop the FLR process
Stop-VBRWindowsFileRestore $restore
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by Mildur »

You're welcome.
There is still no restore point provided in your command. You just run the command Start-VBRWindowsFileRestore without any parameter or inputs.
If you look at the examples in our user guide, you can see that in Example 1, a parameter is used to provide the restore point and in Example 2, a pipe is used to provide the restore point as an input:

https://helpcenter.veeam.com/docs/backu ... ml?ver=110
Example 1 with a parameter:

Code: Select all

$backup = Get-VBRBackup -Name "WinSrv25"
$restorepoint = Get-VBRRestorePoint -Backup $backup -Name "Production VM"
$session = Start-VBRWindowsFileRestore -RestorePoint $restorepoint[1]
Example 2 with an input:

Code: Select all

Get-VBRBackup -Name "WinSrv25" | Get-VBRRestorePoint | Sort-Object –Property CreationTime –Descending | Select-Object -First 1 | Start-VBRWindowsFileRestore
In your script, no input or parameter is provided.

Code: Select all

$restore = Start-VBRWindowsFileRestore 
The script should do this steps:

Code: Select all

1) Import the TXT file
2) Start a Foreach loop for each line in the TXT file:
     a) Get the Job Name from the TXT file
     b) Find backups for the Job with Get-VBRBackup -Name "Job Name"
     c) Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
     d) Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
     e) Get the Mount Point
     f) Copy the files from the Mount Point to a production folder (Each Job should use his own Folder)
     g) Stop the file level restore session with Stop-VBRWindowsFileRestore
3) Script finished
Thanks
Fabian
Product Management Analyst @ Veeam Software
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Thanks, Fabian , that was very helpful
I will work through that logic an update script, again much appricated
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by Mildur »

You're welcome.
Let me know if you have another question.
And if you want, please share the script when it is finished. It could help other members :)
Product Management Analyst @ Veeam Software
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Hi Fabian,

It still isn't working and I'm sure it's something I'm missing .. I've used your annotation so you can see where I've tried to follow every step and it is easier to disect.

I feel it's close but I'm getting something wrong, I'm a hardware engineer by nature so this is a slight departure for me.

Yes of course once i've cracked it (with your help) will share for all :)

Thanks in advance for your help

Code below

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue


#Import the TXT file
#Get Content from Text File
$file = Get-Content jobs.txt
$jobs = Get-VBRJob

#Start a Foreach loop for each line in the TXT file:
foreach($job in $file){

#Get the Job Name from the TXT file
$vbrJob = $jobs | Where-Object {$_.Name -eq "$job"}     #I think this is the part that is incorrect?? #
$vbrJob.Name

#Find backups for the Job with Get-VBRBackup -Name "Job Name"
Get-VBRBackup | Where-Object {$_.Name -eq "$job"}

#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
Get-VBRRestorePoint | sort CreationTime -Descending | where {$_.Name -eq "$vbrjob.Name"} | select -First 1 |

#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
Start-VBRWindowsFileRestore


#Get the Mount Point
#Find the FLR mount point for the specific drive letter
$flrmountpoint = ($restore.MountSesion.MountedDevices | ? {$_.DriveLeter -eq (Split-Path $file -Qualifier)}).MountPoint

#Targeted File or Folder
$originalFiles = "C:\Windows\twain_32"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\test\$job"

# Copies the Files
foreach ($file in $originalFiles) {

# Build the path to the file via the FLR mount point
$file = $flrmountpoint + (Split-Path $file -NoQualifier)

#Copy/Restore the files
Copy-Item $file $destPath -Force -recurse
}}

#Stop the file level restore session with Stop-VBRWindowsFileRestore
#Stop the FLR process
Stop-VBRWindowsFileRestore
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Made another change, and think this is closer ... however where I'm struggling is how to use returned result ?

This section

Code: Select all

#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
$result = Get-VBRBackup | Get-VBRRestorePoint | sort CreationTime -Descending | -name "What to enter here??" | select -First 1
$restore = $result | Start-VBRWindowsFileRestore
Full code below

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue


#Import the TXT file
#Get Content from Text File
$file = Get-Content jobs.txt
$jobs = Get-VBRJob

Start a Foreach loop for each line in the TXT file:
foreach($job in $file){

#Get the Job Name from the TXT file
$vbrJob = $jobs | Where-Object {$_.Name -eq "$job"}
$vbrJob.Name

#Find backups for the Job with Get-VBRBackup -Name "Job Name"
Get-VBRBackup | Where-Object {$_.Name -eq "$job"}

#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
$result = Get-VBRBackup | Get-VBRRestorePoint | sort CreationTime -Descending | -name "VMName" | select -First 1
#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
$restore = $result | Start-VBRWindowsFileRestore





#Get the Mount Point
#Find the FLR mount point for the specific drive letter
$flrmountpoint = ($restore.MountSesion.MountedDevices | ? {$_.DriveLeter -eq (Split-Path $file -Qualifier)}).MountPoint

#Targeted File or Folder
$originalFiles = "C:\Windows\twain_32"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\test\$job"

# Copies the Files
foreach ($file in $originalFiles) {

# Build the path to the file via the FLR mount point
$file = $flrmountpoint + (Split-Path $file -NoQualifier)

#Copy/Restore the files
Copy-Item $file $destPath -Force -recurse
}}

#Stop the file level restore session with Stop-VBRWindowsFileRestore
#Stop the FLR process
Stop-VBRWindowsFileRestore $restore

Thanks again for all the help
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Another update

I think this almost works, appreciate your feedback

Code:

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

#Targeted File or Folder
$originalFiles = "C:\Windows\Web"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$job"


#Import the TXT file
#Get Content from Text File
$file = Get-Content jobs.txt
$jobs = Get-VBRJob

#Start a Foreach loop for each line in the TXT file:
foreach($job in $file){

#Get the Job Name from the TXT file
$vbrJob = $jobs | Where-Object {$_.Name -eq "$job"}
$vbrJob.Name 

#Find backups for the Job with Get-VBRBackup -Name "Job Name"
#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
$result = Get-VBRBackup | Where-Object {$_.Name -eq "$job"} | Get-VBRRestorePoint | Sort-Object –Property CreationTime –Descending | Select-Object -First 1 
$restore = $result | Start-VBRWindowsFileRestore

# Copies the Files
foreach ($file in $originalFiles) {
    
    # Find the FLR mount point for the specific drive letter
    $flrmountpoint = ($restore.MountSession.MountedDevices | ? {$_.DriveLetter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
    $file = $flrmountpoint + (Split-Path $file -NoQualifier)

    #Copy/Restore the files
    Copy-Item $file $destPath -Force -recurse
    }}
    
# Stop the FLR process
Stop-VBRWindowsFileRestore  $restore
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by Mildur »

Do you get an error with the latest version of the script? If so, please share the error message.

Your restore point selection doesn't define from which VM you want todo the restore:

Code: Select all

Get-VBRBackup | Where-Object {$_.Name -eq "$job"} | Get-VBRRestorePoint | Sort-Object –Property CreationTime –Descending | Select-Object -First 1
Change it to:

Code: Select all

Get-VBRBackup | Where-Object {$_.Name -eq "$job"} | Get-VBRRestorePoint -Name "VM-Name" | Sort-Object –Property CreationTime –Descending | Select-Object -First 1 
This must be inside your Restore Loop. You have to close each restore session after you copied the files for a single job.

Code: Select all

# Stop the FLR process
Stop-VBRWindowsFileRestore  $restore
May I ask you, why you want todo restores per job? Normally, you have a single job and dozens of vms.
A list with VMs you want to test the FLR restore process would be better than using a list with jobs.

Thanks
Fabian
Product Management Analyst @ Veeam Software
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Hi Fabian

Get-VBRBackup | Where-Object {$_.Name -eq "$job"} | Get-VBRRestorePoint -Name "VM-Name" | Sort-Object –Property CreationTime –Descending | Select-Object -First 1

Get-VBRRestorePoint -Name "VM-Name" What would i put for VM-Name?

May I ask you, why you want todo restores per job? Normally, you have a single job and dozens of vms.
A list with VMs you want to test the FLR restore process would be better than using a list with jobs.

We have multiple jobs, rather than multiple VMs per job so this seemed the best approach

No error from the latest code but only one VM restore seems to be being processed and only one stops

my test has two jobs, one vm per job

However i am open to the best method, again I'm no PowerShell guru so i'm just going with what i know.
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by Mildur »

If you only have one VM per job, then no vm-name is required.
If you have multiple VMs in a single job, you have to provide the name of the VM you want to restore, or your script will restore a random VM from the job each day you run your script.
No error from the latest code but only one VM restore seems to be being processed and only one stops
That's because you stop only the last session if you use Stop-VBRWindowsFileRestore $restore outside of your foreach loop. This command must be used inside the loop.
Product Management Analyst @ Veeam Software
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Again thanks for the help.

Will change the loop so as to include the stop.

That makes sense.

If there was multiple VMs per job,how would I provide the VM-Name, would I need to add a section to list the VMs in the job then process the results?

What would that look like?

Or Am i best to abandon the jobs approach and do by VM

We do have some jobs with multiple VMs per job ... Depending on client
Mildur
Product Manager
Posts: 8735
Liked: 2296 times
Joined: May 13, 2017 4:51 pm
Full Name: Fabian K.
Location: Switzerland
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by Mildur »

Our recommendation is to use a single job with multiple VMs instead of using one job per VM.
Have a look at our best practice:
https://bp.veeam.com/vbr/4_Operations/O ... ckup_jobs/

I would rebuild the script to use VM Names in your text file. And do FLR restore tests for each vm instead of each job.
Are you using SureBackup Jobs besides this restore tests? Restoring a few files doesn't guarantee you, that the VM can powered on and applications like Active Directory, Exchange or MSSQL server will be able to start.
Product Management Analyst @ Veeam Software
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Still working on the modifications for VM vs job

but in meantime, is there a way to have the destination path name folder using jobname or even VM name being processed

i did try

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$vmname\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$name\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$job"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$job\"


None of which gave the desired result

Really appreciate all the help with this
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Made changes to use VM instead as advised

it doesn't quite work, where did i go wrong?

Code

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

#Targeted File or Folder
$originalFiles = "C:\Windows\Web\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$VMName\"


#Import the TXT file
#Get Content from Text File
$file = Get-Content jobs.txt

#Start a Foreach loop for each line in the TXT file:
foreach($VMName in $file){


#Find backups for the Job with Get-VBRBackup -Name "Job Name"
#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
Get-VBRRestorePoint | sort CreationTime -Descending | where {$_.VMName -eq "$VMName"} | select -First 1 | Start-VBRWindowsFileRestore

# Copies the Files
foreach ($file in $originalFiles) {
    
    # Find the FLR mount point for the specific drive letter
    $flrmountpoint = ($restore.MountSession.MountedDevices | ? {$_.DriveLetter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
    $file = $flrmountpoint + (Split-Path $file -NoQualifier)

    #Copy/Restore the files
    Copy-Item $file $destPath -Force -recurse
    }
    
# Stop the FLR process
Stop-VBRWindowsFileRestore

}

Code: Select all

Error

PS C:\Windows\system32> C:\Users\rpadmin\Veeam_Restore_Scripts\PowerShell\List Test\jobsvm.ps1

Id           : 3b643773-e09c-4278-ba3b-4ab6458f5819
MountPoint   : FELIX-DC_3b643773
Drives       : C:\VeeamFLR\FELIX-DC_3b643773\Volume0, C:\VeeamFLR\FELIX-DC_3b643773\Volume1
VmName       : FELIX-DC
Size         : 80 GB
CreationTime : 8/23/2022 1:24:56 AM
Oib          : Veeam.Backup.Core.COib
MountSession : Veeam.Backup.PowerShell.Infos.CToIMountSessionAdapter

Stop-VBRWindowsFileRestore : Parameter set cannot be resolved using the specified named parameters.
At C:\Users\rpadmin\Veeam_Restore_Scripts\PowerShell\List Test\jobsvm.ps1:38 char:1

Thanks again
+ Stop-VBRWindowsFileRestore
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Stop-VBRWindowsFileRestore], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Veeam.Backup.PowerShell.Cmdlets.StopVBRWindowsFileRestore
 
Start-VBRWindowsFileRestore : File does not exist. File: [FELIX-VEEAM.26D2022-10-06T112051_27A3.vib].
Failed to open storage for read access. Storage: [FELIX-VEEAM.26D2022-10-06T112051_27A3.vib].
Failed to restore file from local backup. VFS link: [summary.xml]. Target file: [MemFs://frontend::CDataTransferCommandSet::RestoreText_{247713d5-c993-4c84-a35a-adffa7e6b23d}]. CHMOD mask: [213].
Agent failed to process method {DataTransfer.RestoreText}.
At C:\Users\rpadmin\Veeam_Restore_Scripts\PowerShell\List Test\jobsvm.ps1:22 char:107
+ ... VMName -eq "$VMName"} | select -First 1 | Start-VBRWindowsFileRestore
+                                               ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Start-VBRWindowsFileRestore], CAppException
    + FullyQualifiedErrorId : Veeam.Backup.Common.CAppException,Veeam.Backup.PowerShell.Cmdlets.StartVBRWindowsFileRestore
 
Stop-VBRWindowsFileRestore : Parameter set cannot be resolved using the specified named parameters.
At C:\Users\rpadmin\Veeam_Restore_Scripts\PowerShell\List Test\jobsvm.ps1:38 char:1
+ Stop-VBRWindowsFileRestore
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Stop-VBRWindowsFileRestore], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Veeam.Backup.PowerShell.Cmdlets.StopVBRWindowsFileRestore
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Hi @wgoodall,

I see two issues:

1. First, you should pass the session you want to stop to Stop-VBRWindowsFileRestore. I actually would not do the big piped one-liner you did for starting the session and instead break it into two parts: One to get the restore point, one to start the session.

$rp = Get-VBRRestorePoint | sort CreationTime -Descending | where {$_.VMName -eq "$VMName"} | select -First 1
$sess = Start-VBRWindowsFileRestore -RestorePoint $rp

Then you'd pass $sess to the Stop-VBRWindowsFileRestore at the end of the loop when its done with the test.

2. Start-VBRWindowsFileRestore : File does not exist. File: [FELIX-VEEAM.26D2022-10-06T112051_27A3.vib].

Looks like for some reason Veeam cannot locate or access the file. If you check on the repository, does this file exist? If you start a File Level Restore manually from the UI, does the same issue occur? If you get the same issue from the UI, I recommend open a Support case and let the Support Team review the logs. Be sure to collect logs as per https://veeam.com/kb1832 and use the 3rd option, selecting the Veeam Server. It should be enough to start the investigation.
David Domask | Product Management: Principal Analyst
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Hey David,

First of all thanks for all the help

1) I made those changes and now it's working, the only issues I now have is auto-generating the destination path based on either the job name or vm from the text list.

I have tried the following but nothing is giving the desired result, is this possible?

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$vmname\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$name\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$job"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\fulltest\$job\"

2) Is there anyway to have it restore a different restore point other than the last good backup? that would be very useful.

3) you were absolutely right, there was an issue with that backup on our test server, which i am now fixing.

Thanks for your continued help, these tests will be used in conjunction with sure backup but are still very important, the code is almost there and will publish the final result to help others.

Wes

Current Code Below

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

#Targeted File or Folder
$originalFiles = "C:\storage\"

[b]#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\VMS\$job"[/b]


#Import the TXT file
#Get Content from Text File
$file = Get-Content VMs.txt

#Start a Foreach loop for each line in the TXT file:
foreach($VMName in $file){


#Find backups for the Job with Get-VBRBackup -Name "Job Name"
#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
$rp = Get-VBRRestorePoint | sort CreationTime -Descending | where {$_.VMName -eq "$VMName"} | select -First 1
$sess = Start-VBRWindowsFileRestore -RestorePoint $rp


# Copies the Files
foreach ($file in $originalFiles) {
    
    # Find the FLR mount point for the specific drive letter
    $flrmountpoint = ($restore.MountSession.MountedDevices | ? {$_.DriveLetter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
    $file = $flrmountpoint + (Split-Path $file -NoQualifier)

    #Copy/Restore the files
    Copy-Item $file $destPath -Force -recurse
    }
    
# Stop the FLR process
Stop-VBRWindowsFileRestore $sess

}
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Hi @wgoodall,

Glad to hear it! Though sorry that there's an issue with the restore point. Feel free to PM me the case number and I'll check in on the case.

As for a custom destination path, that's quite doable but you need to put it inside your look for the restore.

That is within:

foreach ($file in $originalFiles) {

You need to set $destPath there.

The main "issue" is you have nested ForEach loops which isn't necessarily wrong, but it can cause performance issues and you need to keep track of the variable scope. Variables are only accessible within certain scopes; each loop introduces a new scope and right now you have $destPath being set before you're looping over each restore Session/VM, so it tries to set $destPath before you've even initialized the $job variable.

I think if you set $destPath with the VMname or your desired format right after:

foreach ($file in $originalFiles) {

You should see the desired result. It will pass down to the lower loop and be accessible.

The current workflow you have is:

1. Set $originalFiles
2. Set $destPath to $job (which does not exist yet)
3. Import VM list
4. For Each VM in file, start the restore loop
5. Within the restore loop, start an FLR and mount the disks
6. Copy files from the $originalFiles path to $destPath

The problem with this workflow is that the shell has no idea what to do with steps 2 and 6. Step 2 fails because it doesn't know what $job should represent, and step 6 because $destPath is empty as a result.

Instead, you should:

1. Set $originalFiles
2. Import VM list
3. For Each VM in file, start the restore loop
4. Set $destpath at the start of the restore loop based on the VM name or Job name (your preference. VMName you have from step 2, but you can get JobName pretty easily from the $rp variable. I believe it has a BackupID Property which you can use to parse the jobs as they should also have a matching backupID property (I might be wrong on this, I'm not connected to my lab at the moment). Alternatively I'm pretty sure there's an unsupported method FindJob() on the COib objects for the $rp variable you can use to return the job and get the properties from that. See the example below.
5. Start an FLR and mount the disks
6. Copy files from the $originalFiles path to $destPath

That should work.

> 2) Is there anyway to have it restore a different restore point other than the last good backup? that would be very useful.

Sure :) All COib objects (the result of Get-VBRRestorepoint) have a CreationTime property you can parse on. Figuring out which one to use might be tricky though :(

Programmatically, it's not complex to make Powershell take an input date and just find the closest point before/after that date. However, can I ask, do you expect someone will be at the console launching the script? If so, I would suggest a simpler option with Out-GridView where a user just picks a date from a UI launched by Powershell and it loads that point. But, if this is meant to be completely automated, then there is a bit of (semi-complex but easy to write) logic to do this.



Example:

Code: Select all

PS C:\Users\Administrator> $bois

Job Name                  Type            Creation Time               VM count
--------                  ----            -------------               --------
simple-replica            VMware Repli... 9/30/2022 1:24:27 AM               2


PS C:\Users\Administrator> $bois.FindJob()

Job Name                  Type            State      Last Result  Description
--------                  ----            -----      -----------  -----------
simple-replica            VMware Repli... Stopped    Success      Created by DDOM-VEEAM-RB4\Administrator at 9/30/20...


PS C:\Users\Administrator> $bois.CreationTime

Friday, September 30, 2022 1:24:27 AM
David Domask | Product Management: Principal Analyst
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

First of all, thank you David and Midur for all your help, I really have been blown away by how supportive these forums are.

So the code now works as expected, very happy .. code is pasted below to help anyone else who may have a similar need.

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

#Targeted File or Folder
#$originalFiles = "C:\Users\rpadmin\Veeam_Restore_Test_Data\"
$originalFiles = "C:\storage\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\VMS\$job"


#Import the TXT file
#Get Content from Text File
$file = Get-Content VMs.txt

#Start a Foreach loop for each line in the TXT file:
foreach($VMName in $file){

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\VMS\$VMname"



#Find backups for the Job with Get-VBRBackup -Name "Job Name"
#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore
$rp = Get-VBRRestorePoint | sort CreationTime -Descending | where {$_.VMName -eq "$VMName"} | select -First 1
$sess = Start-VBRWindowsFileRestore -RestorePoint $rp


# Copies the Files
foreach ($file in $originalFiles) {
    
    # Find the FLR mount point for the specific drive letter
    $flrmountpoint = ($restore.MountSession.MountedDevices | ? {$_.DriveLetter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
    $file = $flrmountpoint + (Split-Path $file -NoQualifier)

    #Copy/Restore the files
    Copy-Item $file $destPath -Force -recurse
    }
    
# Stop the FLR process
Stop-VBRWindowsFileRestore $sess

}

@David

I like the idea of using gridview and have managed to get PowerShell to output the list of just VMnames and Creationtime for the restore points, but they are not selectable, I can't find much on grid view what else do i need to? .. is there an article i struggled to find anything.

Code: Select all

$rp = Get-VBRRestorePoint | sort CreationTime -Descending | where {$_.VMName -eq "$VMName"} | select-object VMName, CreationTime  | Out-GridView
$sess = Start-VBRWindowsFileRestore -RestorePoint $rp
Thanks again for all your help
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Update

what am i missing, so close :)

$rp = Get-VBRRestorePoint | where {$_.VMName -eq "$VMName"} | select-object VMName, CreationTime | Out-GridView –PassThru
$sess = Start-VBRWindowsFileRestore -RestorePoint $rp

Error

Cannot bind parameter 'RestorePoint'. Cannot convert the "@{AppSrv (Macula)=; CreationTime=10/1/2022 8:32:02 PM}" value of type "Selected.Veeam.Backup.Core.COib" to type "Veeam.Backup.Core.COib".
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Ah! This one is tricky, but I ran into the same thing.

The Select-Object makes a custom Object containing VMName and CreationTime, whereas if you just passed all the parameters, it would pass the COib object.

So, two approaches here:

1. Just remove the Select-Object part
2. Fetch all your Restore Points first into $AllRps, then change $rp to:

$rp = $AllRps | Where {$_.VMName -eq $VMName} | Select-Object VMName, CreationTime, id | Out-GridView -PassThru
$rp = $AllRps | Where-Object {$_.id -eq $rp.id}

See the trick?
David Domask | Product Management: Principal Analyst
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Clever indeed

Let me try that and post back ... So close :)

Thanks again it's so appreciated
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

1) I tested and I'm getting an error, did i do it correctly?

Code: Select all

# Loads Veeam Powershell Snapin
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue

#Set Location
Set-location "$PSScriptRoot"


#Targeted File or Folder
#$originalFiles = "C:\Users\rpadmin\Veeam_Restore_Test_Data\"
$originalFiles = "C:\storage\"

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\VMS\$job"


#Import the TXT file
#Get Content from Text File
$file = Get-Content VMs.txt

#Start a Foreach loop for each line in the TXT file:
foreach($VMName in $file){

#Change Path to match backup Job
$destPath = "C:\Users\rpadmin\Veeam_Restore\VMS\$VMname"



#Find backups for the Job with Get-VBRBackup -Name "Job Name"
#Find the latest restore point for that Job and the required vm with Get-VBRRestorePoint -name "VMName"
#Start the file level restore session for that restore point with Start-VBRWindowsFileRestore–PassThru -OutputMode Multiple
$rp = $AllRps | Where {$_.VMName -eq $VMName} | Select-Object VMName, CreationTime, id | Out-GridView -PassThru
$rp = $AllRps | Where-Object {$_.id -eq $rp.id}
$sess = Start-VBRWindowsFileRestore -RestorePoint $rp




# Copies the Files
foreach ($file in $originalFiles) {
    
    # Find the FLR mount point for the specific drive letter
    $flrmountpoint = ($restore.MountSession.MountedDevices | ? {$_.DriveLetter -eq (Split-Path $file -Qualifier)}).MountPoint

    # Build the path to the file via the FLR mount point
    $file = $flrmountpoint + (Split-Path $file -NoQualifier)

    #Copy/Restore the files
    Copy-Item $file $destPath -Force -recurse
    }
    
# Stop the FLR process
Stop-VBRWindowsFileRestore $sess

}

Error:

Start-VBRWindowsFileRestore : Cannot validate argument on parameter 'RestorePoint'. The argument is null. Provide a valid value for the argument, and then try running the command again.
At C:\Users\guardian\Veeam_Restore_Scripts\SelectRestorePoint\SelectRestore.ps1:33 char:51
+ $sess = Start-VBRWindowsFileRestore -RestorePoint $rp
+ ~~~
+ CategoryInfo : InvalidData: (:) [Start-VBRWindowsFileRestore], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Veeam.Backup.PowerShell.Cmdlets.StartVBRWindowsFileRestore


Thanks again for helping me out


2) I also meant to ask is there any way to output an audit log after the script has ran?
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Hey @wgoodall,

Code: Select all

It's a little strange, cause it should work. Just double-checked in my lab and I got this:

PS C:\Users\Administrator> $VMName = 'ddom-tinyvm'
PS C:\Users\Administrator> $rp = $AllRps | Where {$_.VMName -eq $VMName} | Select-Object VMName, CreationTime, id | Out-GridView -PassThru
PS C:\Users\Administrator> $newRp = $AllRPs |?{$_.id -eq $rp.id}
PS C:\Users\Administrator> $newRp

VM Name                   Creation Time          Type
-------                   -------------          ----
ddom-tinyvm               10/11/2022 8:41:24 AM  Increment
The error means that $rp was NULL, i.e., nothing was saved to it, so I have to assume there was a failure at some point to get an RP correctly.

1. Did the Out-GridView window actually appear or no?
2. If it did not, I would guess it's this part came back empty: $AllRps | Where {$_.VMName -eq $VMName}

That would make me think it could not find a Restore Point where the VMName matched the one from your file.

For adding debugging, you'll need to write your own logging.

Add a function like this:

Code: Select all

$logentry = "$(Get-Date) ::: "
$logpath = C:\temp\scriptdebuglog.log
function Write-Log {
    param(
        [string[]]$LogText
        )
    Add-Content -Path $logpath -Value "$logentry $LogText"
    }
Then add the function in key places and pass to -LogText some interesting things for you. For example, I'd be curious in the look to check the value of

$VMname
$rp
$rp after you set it from $AllRps

You can write the text of the entry to be informative to yourself and see.

You can clean up your final script by just removing any invocation of Write-Log
David Domask | Product Management: Principal Analyst
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Hi David,

Sorry for the late response, been really busy and haven't had a chance to get back to the scripting, in meantime whilst I look into it, is there any way i can have the script produce a report at the end, to say which restores failed, etc?

Thanks again for all your help

Wes
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Heya @wgoodall,

No worries, I understand.

For Powershell, the way to do this is Try/Catch statements:

https://learn.microsoft.com/en-us/power ... rshell-7.2

Basically you'll put the actual restore attempt into a Try/Catch statement; if there are any errors, the catch should add some information into an array/report elsewhere noting whatever information you seek.
David Domask | Product Management: Principal Analyst
wgoodall
Enthusiast
Posts: 28
Liked: never
Joined: Aug 30, 2022 6:21 am
Full Name: Wesley Goodall
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by wgoodall »

Sorry again for the lateness, we have been focusing on other things, and have just got back to looking at this.

That's great, thanks again ... i'll look into that.

One thing i did notice with the restore test, is that if the destination folder already exists it doesn't seem to overwrite it (the modified date in windows stays the same), is there a switch to force it to overwrite?

Thansk again
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Sure, good luck on your testing.

For the path item, use the New-Item cmdlet with the -Force flag. This is in MacOS Powershell 7, but the behavior is same on Windows.

Code: Select all

PS /Users/vvvvvv/Downloads> New-Item -Path /Users/vvvvvv/Downloads/test -Type Directory

    Directory: /Users/vvvvvv/Downloads

UnixMode   User             Group                 LastWriteTime           Size Name
--------   ----             -----                 -------------           ---- ----
drwxr-xr-x vvvvvv           staff              10/28/2022 11:56             64 test

PS /Users/vvvvvv/Downloads> New-Item -Path /Users/vvvvvv/Downloads/test -Type Directory
New-Item: An item with the specified name /Users/vvvvvv/Downloads/test already exists.
PS /Users/vvvvvv/Downloads> New-Item -Path /Users/vvvvvv/Downloads/test -Type Directory -Force

    Directory: /Users/vvvvvv/Downloads

UnixMode   User             Group                 LastWriteTime           Size Name
--------   ----             -----                 -------------           ---- ----
drwxr-xr-x vvvvvv           staff              10/28/2022 11:56             64 test
David Domask | Product Management: Principal Analyst
david.domask
Veeam Software
Posts: 1226
Liked: 323 times
Joined: Jun 28, 2016 12:12 pm
Contact:

Re: Powershell script to restore from multiple jobs using a text file

Post by david.domask »

Small warning though :) Force will nuke existing data there, so make sure it's the right directory ;)
David Domask | Product Management: Principal Analyst
Post Reply

Who is online

Users browsing this forum: No registered users and 13 guests