Skip to main content

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

 

Thank you, very usefull script.

Tested and found 2 VMs without backups ;-)

 


Thank you, very usefull script.

Tested and found 2 VMs without backups ;-)

 

So sharing the script has already paid off!

:thumbsup:


Excellent resource. Thanks a lot. 

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


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. 

 


really very usable!
Thank you


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"


@vNote42 : Wonderful, It is used for Audit for sure :) 


@vNote42 I 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.


@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:


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


@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….


@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...😅


@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.


@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.


@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.


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.


Very usable! Thank you for this share.


Very usable! Thank you for this share.

You are welcome!


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 


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.


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 ? 

 

 

 


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.


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.


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, …?


just a regular vmdk backup.

thank for looking into this. 


Comment