Note: I had a first idea about a way to do these checks and you will still find traces of it in Veeam forums, however the ongoing discussion has lead to this present version, and it’s really different from the original code, and much better. Kudos for Powershell cod e goes to Tom Sightler and in part also to Seth Bartlett, if you find this script useful say thanks to them.
There are situations where the answer to this is not always a cleat YES. Maybe you are managing hundreds or thousands of VM, maybe you have an environment where VM creation and deletion is frequent, or there are many sysadmins working together.
All these situations can lead to changes in the VM list, and if not all of these are configured in the backup jobs one by one, you can dangerously forget some of them… and find it out when you would need a restore of it!
To ease this problem, there is a preventive method and a way to check the status, both feasable with Veeam Backup.
Use containers instead of VM lists
You can configure Veeam Backup jobs and manually add single VMs in it. When a new VM is created in the VMware infrastructure you need to add it the the existing backup job.
You can however simplify this procedure using containers: if for example you use a resource pool as your backup object, or a datastore or the entire vCenter structure, VM list is created dinamically at every backup execution reading it from vCenter itself. In vCloud environments resource pool is a great way of doing backups, since everyone is a tenant so every backup job is mapped to a customer.
Check Script
There are anyway some exceptions where even this method has some limits. If you add a new resource pool (manually or by the creation of a new vCloud tenant) or a new datastore, this is not added to any existing backup job. Or you have previously excluded a single VM from a backup job, maybe because it was only a test machine you did not want to save (we are all surrounded by test VM that suddenly go into production)
To solve these problems, you can run a Powershell script to check the status of your backup. Kudos to Veeam for implementing Powershell cmdlets for all its operations.
This script has to be executed on Veeam Server, where you need to choose also the Powershell cmdlets while installing the software. You have to configure $vcenter variable using the hostname or the IP address, and run the script with a user that can access Veeam Server; the scripts then connects to vCenter using saved credentials when you registered vCenter in Veeam Backup.
The script retrieves from vCenter the full list of all existing VMs, and for each of them checks if there is a backup (with Success or Warning result) in the last 24 hours. You can change this value by modifying the string (Get-Date).addhours(-24) where 24 is the hours you want to check in the past.
Once you run the script, the result will be like this:
As you can see, protected VMs are coloured in green, unprotected in red. This is a super-easy way to check which VMs are protected, and correct your omissions. By changing 24 hours value, you can go back in time to check non daily backups. Here I tested last 48 hours, and you can see some VMs are now green while they were red in the previous run:
In the $excludevms you can list, comma separated, some VMs you do not want to check, maybe because you do not want to backup them.
This is the complete script code:
asnp "VeeamPSSnapIn" -ErrorAction SilentlyContinue #################################################################### # Configuration # vCenter server $vcenter = "vcenter_ip" # To Exclude VMs from report add VM names to be excluded as follows # $excludevms=@("vm1","vm2") $excludevms=@() #################################################################### $vcenterobj = Get-VBRServer -Name $vcenter $vmobjs = Find-VBRObject -Server $vcenterobj | Where-Object {$_.Type -eq "VirtualMachine"} $jobobjids = [Veeam.Backup.Core.CHierarchyObj]::GetObjectsOnHost($vcenterobj.id) | Where-Object {$_.GetItem().Type -eq "Vm"} # Convert exclusion list to simple regular expression $excludevms_regex = (‘(?i)^(‘ + (($excludevms |foreach {[regex]::escape($_)}) –join “|”) + ‘)$’) -replace "\\\*", ".*" foreach ($vm in $vmobjs) { $jobobjid = ($jobobjids | Where-Object {$_.ObjectId -eq $vm.Id}).Id if (!$jobobjid) { $jobobjid = $vm.FindParent("Datacenter").Id + "\" + $vm.Id } $vm | Add-Member -MemberType NoteProperty "JobObjId" -Value $jobobjid } # Get a list of all VMs from vCenter and add to hash table, assume Unprotected $vms=@{} foreach ($vm in ($vmobjs | where {$_.Name -notmatch $excludevms_regex})) { if(!$vms.ContainsKey($vm.JobObjId)) { $vms.Add($vm.JobObjId, @("!", [string]$vm.GetParent("Datacenter"), $vm.Name)) } } # Find all backup job sessions that have ended in the last 24 hours $vbrjobs = Get-VBRJob | Where-Object {$_.JobType -eq "Backup"} $vbrsessions = Get-VBRBackupSession | Where-Object {$_.JobType -eq "Backup" -and $_.EndTime -ge (Get-Date).addhours(-24)} # Find all successfully backed up VMs in selected sessions (i.e. VMs not ending in failure) and update status to "Protected" foreach ($session in $vbrsessions) { foreach ($vm in ($session.gettasksessions() | Where-Object {$_.Status -ne "Failed"} | ForEach-Object { $_ })) { if($vms.ContainsKey($vm.Info.ObjectId)) { $vms[$vm.Info.ObjectId][0]=$session.JobName } } } $vms = $vms.GetEnumerator() | Sort-Object Value # Output VMs in color coded format based on status. foreach ($vm in $vms) { if ($vm.Value[0] -ne "!") { write-host -foregroundcolor green (($vm.Value[1]) + "\" + ($vm.Value[2])) "is backed up in job:" $vm.Value[0] } else { write-host -foregroundcolor red (($vm.Value[1]) + "\" + ($vm.Value[2])) "is not found in any backup session in the last 24 hours" } }