Skip to main content

First time sharing, so feedback is much appreciated. There is a lot improvement possible but this short script did the trick. 
A while ago we came across an issue after automation made some unforeseen changes to the vm. 
Therefore I was tasked with the restore of a system file from +1000 vms from a specific date (not the last backup)

  • VBR backup 
  • Agent backups
  • Netapp snapshot only

The CSV file exists out the vm name & backupjob name for the VBR & Agent restores. (extracted this from the notes in vcenter where possible)
For the netapp restore the vmname was only needed.

Here is the script that made my life easier:

function Get-TimeStamp 
{
return Get-Date -UFormat "a%Y-%m-%d %T]"
}


# Starting script
# --
Write-Host "$(Get-TimeStamp) - Starting script"

$vmlist = import-csv C:\scripts\Veeam\restore\vmlist.csv -Delimiter ";"

Foreach ($vm in $vmlist) {
$backupjob = $vm.backupjob
$asset = $vm.vm

$backup = Get-VBRBackup -Name $backupjob
$restorepoint = Get-VBRRestorePoint -Backup $backup -Name $asset | where-object{($_.CreationTime|get-date -Format 'dd/MM/yyyy hh:mm:ss') -like "02/05/2023 *"}
Write-Host "$(Get-TimeStamp) - start Restore"
$restorestart = Start-VBRWindowsFileRestore -RestorePoint $restorepoint
Write-Host "$(Get-TimeStamp) - Validate running sessions"
$runningsession = Get-VBRRestoreSession | Where-Object {$_.state -eq "working" -and $_.Name -eq "FLR_F$asset]"}
write-host $runningsession
Write-Host "$(Get-TimeStamp) - Search item in backup"
$items = Get-VBRWindowsGuestItem -Session $runningsession -Path "<c:\windows\system32\file>"

if (!(test-path "E:\#restore\$asset")){
Write-Host "$(Get-TimeStamp) - create directory"
mkdir "E:\#restore\$asset"
Write-Host "$(Get-TimeStamp) - Copy item asset to folder"
Copy-VBRWindowsGuestItem -Item $items -TargetFolder "E:\#restore\$asset" -session $runningsession
Write-Host "$(Get-TimeStamp) - Copy complete from $asset"

Stop-VBRWindowsFileRestore $restorestart
write-host "$(Get-TimeStamp) - Stop Restore Session"

}else{
Write-Host "$(Get-TimeStamp) - directory already exists"
Write-Host "$(Get-TimeStamp) - Copy item asset to folder"
Copy-VBRWindowsGuestItem -Item $items -TargetFolder "E:\#restore\$asset" -session $runningsession
Write-Host "$(Get-TimeStamp) - Copy complete from $asset"

Stop-VBRWindowsFileRestore $restorestart
write-host "$(Get-TimeStamp) - Stop Restore Session"
}
}

For Netapp snapshot only backup I had to adjust the script to specify ESX host/resource/folder
 

function Get-TimeStamp 
{
return Get-Date -UFormat "m%Y-%m-%d %T]"
}


# Starting script
# --
Write-Host "$(Get-TimeStamp) - Starting script"

$vmlist = import-csv C:\scripts\Veeam\restore\vmlist.csv -Delimiter ";"

Foreach ($vm in $vmlist) {

$asset = $vm.vm
$esxhost = "<name of host>"
$foldername = "Discovered virtual machine"

$restorepoint = Get-VBRRestorePoint -name $asset | where-object{($_.CreationTime|get-date -Format 'dd/MM/yyyy hh:mm:ss') -like "<date> *"}

$server = get-vbrserver | where {$_.name -eq $esxhost}
$res = Find-VBRViEntity -ResourcePools -Server <vcentername> -name "resources" | where{$_.path -eq "<path to resources>"} #found multiple resources otherwhise
$folder = Find-VBRViFolder -server $server -name $foldername
Write-Host "$(Get-TimeStamp) - start Restore"
$restorestart = Start-VBRWindowsFileRestore -RestorePoint $restorepoint -ResourcePool $res -Host $server -Folder $folder
Write-Host "$(Get-TimeStamp) - Validate running sessions"
$runningsession = Get-VBRRestoreSession | Where-Object {$_.state -eq "working" -and $_.Name -eq "FLR_"$asset]"}
Write-Host "$(Get-TimeStamp) - Search item in backup"
$items = Get-VBRWindowsGuestItem -Session $runningsession -Path "c:\windows\system32\<file>"

if (!(test-path "E:\#restore\$asset")){
Write-Host "$(Get-TimeStamp) - create directory"
mkdir "E:\#restore\$asset"
Write-Host "$(Get-TimeStamp) - Copy item asset to folder"
Copy-VBRWindowsGuestItem -Item $items -TargetFolder "E:\#restore\$asset" -session $runningsession
Write-Host "$(Get-TimeStamp) - Copy complete from $asset"

Stop-VBRWindowsFileRestore $restorestart
write-host "$(Get-TimeStamp) - Stop Restore Session"

}else{
Write-Host "$(Get-TimeStamp) - directory already exists"
Write-Host "$(Get-TimeStamp) - Copy item asset to folder"
Copy-VBRWindowsGuestItem -Item $items -TargetFolder "E:\#restore\$asset" -session $runningsession
Write-Host "$(Get-TimeStamp) - Copy complete from $asset"

Stop-VBRWindowsFileRestore $restorestart
write-host "$(Get-TimeStamp) - Stop Restore Session"
}
}

The netapp restore took a lot longer than my vbr restores. 

 

Hope this can help others as well. 

Greetz

 

Anything PowerShell related is great to share. 👍


Comment