Hey Craig,
To be honest, this feels over-engineered, especially when an in UI solution exists with Backup Copies + immediate mode and rotated drives. I get that you don't want to rock the boat, but if you can do it without scripts and get the same result, why not? I would propose the workflow:
1. Backup Copy Job targeting the repository backed by rotated drives:
https://helpcenter.veeam.com/docs/backu ... ml?ver=110
2. Swap the drives on the week desired, and it will follow the retention scheme as you like
Remember, since the retention is across __all__ drives for Windows, not per drive, you will need to accommodate accordingly with your planning.
But I think this is a lot simpler.
If you really must go down this route, I'd use the Veeam Powershell console itself to get your storages paths (vbks + vibs) and use native sorting.
Get the Backup Chain and Storages (vbk + vibs). I sort by CreationTime here for convenience for me mentally:
Code: Select all
PS C:\Users\Administrator> $backup = Get-VBRBackup -name 'vmware-pervm-ffi
PS C:\Users\Administrator> $storages = $backup.GetAllChildrenStorages() | sort -Property CreationTime
I pull out the fulls with the following (we'll use them for their CreationTime as part of the filter later on):
Code: Select all
$Fulls = $storages |Where-Object {$_.IsFull -eq $true}
Then we can add the chain to some array $Chain like so (of course, you will have to design logic to figure out which item from the index to call, so the below is an __example__ of a backup with two chains (full + increments)):
Code: Select all
$Chain += $Fulls[-1]
$Chain += $storages | Where-Object {$_.IsFull -eq $false -and $_.CreationTime -gt $Fulls[-1].CreationTime -and $_.CreationTime -lt $Fulls[0].CreationTime}
Your end result is:
Code: Select all
PS C:\Users\Administrator> $Chain |select PartialPath, CreationTime
PartialPath CreationTime
----------- ------------
vmware-pervm-ffiD2021-04-03T183823_31F5.vbk 4/3/2021 18:36:35
vmware-pervm-ffiD2021-04-09T183637_1B21.vib 4/9/2021 18:36:37
vmware-pervm-ffiD2021-04-08T183640_841F.vib 4/8/2021 18:36:40
vmware-pervm-ffiD2021-04-07T183655_108A.vib 4/7/2021 18:36:55
vmware-pervm-ffiD2021-04-06T183646_5091.vib 4/6/2021 18:36:46
vmware-pervm-ffiD2021-04-05T183654_D525.vib 4/5/2021 18:36:54
vmware-pervm-ffiD2021-04-04T183650_F7A9.vib 4/4/2021 18:36:50
Finally, you can use the .FilePath.ToString() combo to get a file path you can send to Robocopy. (I changed the backup I used here because the first one was on a scale-out repo, which has special handling -- see below)
Code: Select all
PS C:\Users\Administrator> $storages2[0].filePath.Tostring()
E:\offloadbackup\TinyVM_migrated.vm-6756D2021-04-15T220107_5E10.vib
You can do this to get all paths and write to something like $Paths
Then you can pass the $Paths array to Robocopy somehow (I'm not sure how robocopy will handle the array), and be done with it.
Note there are a few caveats -- with scale-out repositories, you have to first get the extent and the file path for the storage, so this gets a little tricky. I repurposed this a bit for v11 from a post I found earlier on the forums (I think it was Tom Sightler who wrote it?), but this can work if you pass a Backup that is on a scale out repo:
Code: Select all
$Repository = $Backup.FindRepository()[0]
$StoragePathsandBlocksize = @()
if($Repository.Type -eq "ExtendableRepository"){
foreach($Storage in $Storages){
$Extent = $Repository.FindRepositoryForExistingStorage($Storage.Id)
$job = $Backup.FindJob()
$StoragePathsandBlocksize += New-Object -TypeName psobject -Property @{Extent=$Extent.Name;Path=$($Extent.Path.ToString(),$job.Name.ToString(),$Storage.filepath -join "\");BlockSize=$Storage.BlockAlignmentSize;CreationTime=$Storage.CreationTime}
}
this should produce the desired item; you will need to do some handling though if you have Linux based repositories, as you can see that the -join uses a Windows path delimiter.
Anyways, hope this helps (it was a fun afternoon puzzle), but all in all, I recommend avoid this and just use Backup Copies.