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