[PowerShell, PowerCLI] Check for VMs that are not being backuped


Userlevel 7
Badge +7
  • Veeam Legend, Veeam Vanguard
  • 871 comments

If you do not run VeeamONE, it can be challenging to check if every VM that should be backed up, is really backed up. Therefore I wrote a small PowerShell script. 

Basically this script looks for each VM if there is a restore point for this VM. If not, it gets listed. 

Extra feature: 

  • Script connects to every vCenter that is registered in B&R server.
  • There is a Blocklist included: when VMs should not be backuped, just place their name in the blocklist and they will not be shown in the list. So you can exclude VMs without editing the script.

Notes:

  • CredObject.xml is used for stored, encrypted credentials.
  • Script connects to local B&R server, so it should run there if not changed.

 

# Load Plugin and module
Add-PSSnapin VeeamPSSnapin
Import-Module VMware.VimAutomation.Core

# Configure for multiple vCenter Connections
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Scope Session -Confirm:$false
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Scope Session -Confirm:$false

# Connect to local B&R Server
Connect-VBRServer -Server localhost

# Read Credential-File
$WorkingDir = "C:\_install\script\"
$CredObject = Import-Clixml -Path ($WorkingDir + "CredObject.xml")

# Connect to vCenter servers, added to B&R server
Get-VBRServer -Type VC | ForEach-Object {
Connect-VIServer $_.name -Credential $CredObject -ErrorAction Continue
}

# Read VMs in blocklist
$Blocklist = Get-Content -path ($WorkingDir + "Blocklist.txt") -ErrorAction SilentlyContinue | Foreach {$_.TrimEnd()}

# Read all VMs
$VMs = Get-VM | select Name, MemoryGB, PowerState, VMHost, Folder

# Query Veeam Restore Points
$result = @()
$VbrRestore = Get-VBRBackup | Where-Object {$_.jobtype -eq "Backup"} | ForEach-Object {$Jobname = $_.jobname; Write-Output $_;} | Get-VBRRestorePoint | Select-Object vmname, @{n="Jobname"; e={$Jobname}} |Group-Object vmname
$VbrRestore = $VbrRestore | ForEach-Object {$_.Group | Select-Object -first 1}

# Check, if VM on blocklist and a restore point exists
$VMs | ForEach-Object {
if (($_.name -notin $Blocklist) -and ($_.name -notin $VbrRestore.vmname)) {
$result += $_
}
}
$result | ft -AutoSize

# Close connections
Disconnect-VIServer * -Confirm:$false
Disconnect-VBRServer

 


34 comments

Userlevel 1

I was hoping that Veeam Legend would be kind enough to help us out with that :) 

Userlevel 7
Badge +7

You are right. You have to ask yourself if it is a good idea to define a VM as backed up when the newest restore point is 3 years old. You can add some logic to the script to calculate the age of a each restore point. Then you have to decide how old a restore point can be to take a VM as currently backed up. 

Userlevel 1

good point

That shows restore points from the query. 

Those backups are too old for us to be used anyway, I think what I will do is to purge them and set up new one for that box. I don’t see any other servers with this problem. 

 

I realize this might be off topic but is there a script that would get us output of restore points older than x years and purge ones older than specified date or is it all based on configured retention only? 

Userlevel 7
Badge +7

that is just a addition to the name we add in Vsphere , if I try to use that in a query. 

 

The only thing that might have changed would be restore from backup but can’t say for sure. 

you forgot quotes: Get-VBRRestorePoint -Name “STVP-UT11 Print Server”

Userlevel 1

that is just a addition to the name we add in Vsphere , if I try to use that in a query. 

 

The only thing that might have changed would be restore from backup but can’t say for sure. 

Userlevel 7
Badge +7

no results on it , interesting 

I get results on other Systems but not this one

 

What is that mean exactly ? 

Could it be, you changed the name of the VM in the last 1024 days? But also the VM-name is not correct in your query:

 

Userlevel 7
Badge +4

Does this VM have a parent backup job or is it an imported backup? Just a guess from my side, but Get-VBRRestorePoint could possibly only show restorepoints for existing jobs.

Userlevel 1

no results on it , interesting 

I get results on other Systems but not this one

 

What is that mean exactly ? 

Userlevel 7
Badge +7

just a regular vmdk backup.

thank for looking into this. 

I would run the command Get-VBRRestorePoint to see if the restore point is reported.

Userlevel 1

just a regular vmdk backup.

thank for looking into this. 

Userlevel 7
Badge +7

got if , thank you 

updated #Read All VMs section with this 

# Read all VMs
$VMs = Get-VM | Where {$_.PowerState -match "On"} | select Name, MemoryGB, VMHost, Folder

 

and $results with

$result  | sort-Object -Property Name | ft -AutoSize 

 

I do have one result that detects a VM as non-backed up but it actually has a restore point that is 1024 days old , is there a timeframe or some threshold this will not look beyond ? 

 

 

 

good question about you old restore point! What kind of restore point is it? tape, copy, backup, GFS, …?

Userlevel 7
Badge +7

great script!

 

question , can results be sorted out by name and not include powered off vms?

I see that you only use format as table and autosize

Thanks 

Hi @LKTA !

You can just remove ft -AutoSize from $result | ft -AutoSize. Then you get a array as result you can pipe to sort/group/… as you want.

Userlevel 7
Badge +6

got if , thank you 

updated #Read All VMs section with this 

# Read all VMs
$VMs = Get-VM | Where {$_.PowerState -match "On"} | select Name, MemoryGB, VMHost, Folder

 

and $results with

$result  | sort-Object -Property Name | ft -AutoSize 

 

I do have one result that detects a VM as non-backed up but it actually has a restore point that is 1024 days old , is there a timeframe or some threshold this will not look beyond ? 

 

 

 

Yeah just like that.  Nice work.  For the timeframe I would assume the seciton for Query Veeam Restore points would need to be tweaked for this.

Userlevel 1

got if , thank you 

updated #Read All VMs section with this 

# Read all VMs
$VMs = Get-VM | Where {$_.PowerState -match "On"} | select Name, MemoryGB, VMHost, Folder

 

and $results with

$result  | sort-Object -Property Name | ft -AutoSize 

 

I do have one result that detects a VM as non-backed up but it actually has a restore point that is 1024 days old , is there a timeframe or some threshold this will not look beyond ? 

 

 

 

Userlevel 7
Badge +6

great script!

 

question , can results be sorted out by name and not include powered off vms?

I see that you only use format as table and autosize

Thanks 

You could do this by doing a For-Each loop where the VM is equal to powered on only and then the format line can be changed to sort by name also.

Userlevel 1

great script!

 

question , can results be sorted out by name and not include powered off vms?

I see that you only use format as table and autosize

Thanks 

Userlevel 7
Badge +7

Very usable! Thank you for this share.

You are welcome!

Userlevel 7
Badge +3

Very usable! Thank you for this share.

Userlevel 7
Badge +7

Excellent resource. Thanks a lot. 

Will it be still valid for future releases or you need to do some housekeeping stuff?

Thanks!

Good question. The beauty when using PowerShell is the compatibility. This Script will work in v9, v10 and v11 as well. 

 

For V11 you need to change the “Add-PSSnapin VeeamPSSnapin” with "Import-Module Veeam.Backup.PowerShell"

You can, but you have also these options:

  • leave it as it is
  • remove the add-pssnapin… line

Everything works because because it is module now, PowerShell adds this module automatically as soon as you run a cmdlet out of it.

Important here: if you do nothing after upgrading to v11, everything works as before, you just get an error when running add-pssnaping, because the Snapin does not exists any more. Unless you do some advanced error-handling within PowerShell. This could stop your script if programmed that way.

Userlevel 7
Badge +7

@JMeixnerWell the backup user could have only limited permissions on a certain container/folder, because of security reasons. On the other hand I think it's a very unlikely scenario that you're missing VMs in the backup on which you don't have access...😅


This is what I thought 😎

But it is possible… on the other hand, this can happen with PowerCLI, too.

You would not need to login to vSphere. So you do not need to take care about authentication.

Userlevel 7
Badge +7

@vNote42I thought about your script (which is very useful by the way) and wondered if we could remove the PowerCLI as a dependency. We could query all VMs with the Veeam cmdlet “Find-VBRViEntity”; given that the Veeam account can see all VMs.

$VMs = Find-VBRViEntity -VMsAndTemplates | where id -like "*VM*"

Any thoughts on this? Do I forget something here, which could result in wrong or missing results?

 

Also is there a way via to get the VMware MoRef ID with the Veeam Powershell? I know this value is in the database, but I couldn’t find it in the Powershell. This way we could create a 100% match for VM/restorepoint.

Good idea @regnor ! I resinized find-vbrvientity some time ago. But I did not test any further. Would be a nice feature not to need PowerCLI any more. But you are probably right, you will just get VMs the user has permissions for.

I will try it, when I next need the script :slight_smile:


The Veeam user should have permission to access all VMs, shouldn't it? Otherwise you are not able to backup all of your VMs….

Is not a must. I have a customer, backing up about half VMs with Veeam, other half of VMs with another vendors product. Currently Veeam-Users sees all VMs (we migrate all VMs backup to Veeam :sunglasses: ). With PowerCLI it is much easier to select VMs in such a scenario.

Userlevel 7
Badge +5

@JMeixnerWell the backup user could have only limited permissions on a certain container/folder, because of security reasons. On the other hand I think it's a very unlikely scenario that you're missing VMs in the backup on which you don't have access...😅


This is what I thought 😎

But it is possible… on the other hand, this can happen with PowerCLI, too.

Userlevel 7
Badge +4

@JMeixner Well the backup user could have only limited permissions on a certain container/folder, because of security reasons. On the other hand I think it's a very unlikely scenario that you're missing VMs in the backup on which you don't have access...😅

Userlevel 7
Badge +5

@vNote42I thought about your script (which is very useful by the way) and wondered if we could remove the PowerCLI as a dependency. We could query all VMs with the Veeam cmdlet “Find-VBRViEntity”; given that the Veeam account can see all VMs.

$VMs = Find-VBRViEntity -VMsAndTemplates | where id -like "*VM*"

Any thoughts on this? Do I forget something here, which could result in wrong or missing results?

 

Also is there a way via to get the VMware MoRef ID with the Veeam Powershell? I know this value is in the database, but I couldn’t find it in the Powershell. This way we could create a 100% match for VM/restorepoint.

Good idea @regnor ! I resinized find-vbrvientity some time ago. But I did not test any further. Would be a nice feature not to need PowerCLI any more. But you are probably right, you will just get VMs the user has permissions for.

I will try it, when I next need the script :slight_smile:


The Veeam user should have permission to access all VMs, shouldn't it? Otherwise you are not able to backup all of your VMs….

Userlevel 7
Badge +6

Another great script to add to my repo of scripts.  Thanks for the contribution. :smiley:

Comment