The Surly Admin

Father, husband, IT Pro, cancer survivor

Report All Snapshots in Your VMware Environment

One of the fallouts of the outage I had this week (Read Here) was that my backups for that night were stopped. Since Veeam creates snapshots to do it’s backups those snapshots were left on the server. The next night another backup came in and created another snapshot, and the very next day…

File Server Down

Another small outage happened on Friday because my backups were still running, and now I had 2 snapshots on my servers. This was too much for my File Server and suddenly my VMware datastore ran out of space. The frustrating part of this is I have an alerting system to tell me about this kind of thing and it worked perfectly! Unfortunately Outlook decided the alerts were SPAM and plopped them into the Junk Mail folder, which I didn’t find until after the outage. –Facepalm—

Not a huge deal, expanded the datastore and the server was back up within 15 minutes but shouldn’t have happened, especially since I was alerted about an hour before the problem occurred! Maybe my Microsoft Outlook saw it was a VMware alert and decided to mess with me? Or just the gods of fate? Or Murphy?


So while doing this, I wanted to know what snapshots I had out there so I could clean up after this mess. My first command (from PowerCLI) was this:

Get-VM | Get-Snapshot

Which was OK, as you can see:

getsnapshotThe problem here is you can’t tell which VM has the snapshot, just that the snapshot exists. Turns out there is a VM property in Get-Snapshot, so it was just a matter of using Select to get that information.

getsnapshotvmBut by now, you must know I can never let something sit at just that. I wanted to produce a nice HTML report, and something that could be run as a scheduled task. Luckily, most of the pieces we’ll need have already been written and it’s just a matter of pulling it in.

Script Requirements

  1. Load PowerCLI tools
  2. Connect to VMware host or vCenter
  3. Save credentials in a secure file, and be able to use those credentials on multiple computes
  4. Produce a HTML report and save it

Loading Powershell snap-ins–the PowerCLI tools are simply a Powershell snap-in–is pretty easy and well documented, but I wanted to put some intelligence into the loading:

If (-not (Get-PSSnapin VMware.VimAutomation.Core))
{  Try { Add-PSSnapin VMware.VimAutomation.Core -ErrorAction Stop }
   Catch { Write-Host "Unable to load PowerCLI, is it installed?" -ForegroundColor Red; Break }

Just used Get-PSSnapin to see if the tool is loaded or not, if not go ahead and load the snap-in. Used Try/Catch to do some error checking and break out of the script if something goes wrong.

Next we need to connect to the VMware Host or vCenter server. Luckily this is the same process no matter what you’re connecting to. The other piece is we need to use the Credential parameter and we need to save it, which is where I pull up my GetCredentials function I wrote awhile back. One change I made to it was to add a custom encryption key, which is something I ran across over on Poshcode–thanks Daniel, whoever you are! What’s nice about a custom encryption key is that it can be used on several different computers instead of having to encrypt a file for every computer. Normally when you use the SecureString parameter or cmdlet it will use a key unique to the computer you’re on, so you would be unable to decrypt it on another computer. The custom key feature removes that problem.

So we’ll add that to our function and then use Connect-VIServer to connect to the VMware host or vCenter server.

$Cred = GetCredentials $Admin $PathToCredentails
Connect-VIServer $VIServer -Credential $Cred | Out-Null

I’ve updated the GetCredentials script on Spiceworks too if you want to look at it. We’ve got 3 of our steps done now. I reuse some HTML techniques and add that to the script then simply use the Get-VM | Get-Snapshot code from above.

$Report = Get-VM | Get-Snapshot | Select VM,Name,Description,@{Label="Size";Expression={"{0:N2} GB" -f ($_.SizeGB)}},Created
If (-not $Report)
{  $Report = New-Object PSObject -Property @{
      VM = "No snapshots found on any VM's controlled by $VIServer"
      Name = ""
      Description = ""
      Size = ""
      Created = ""
$Report = $Report | Select VM,Name,Description,Size,Created | ConvertTo-Html -Head $Header -PreContent "<p><h2>Snapshot Report - $VIServer</h2></p><br>" | Set-AlternatingRows -CSSEvenClass even -CSSOddClass odd

A very common thing that should happen to you with this report is that no snapshots will be present, and we need the report to be able to handle that. I decided to build a PSObject that matches the output from the Get-Snapshot cmdlet just to keep the report consistent. After that we export to HTML and set alternating row colors to make it look nice. Than it’s a simple matter of sending the report to the Out-File cmdlet and save.

$Report | Out-File $PathToReport\SnapShotReport.html

Here’s some sample output:

snapshotsnosnapshotsIf you wanted, you could add Send-MailMessage to the end script and have it email you the report too, depending on what you want to do.

Download Get-Snapshots


March 18, 2013 - Posted by | PowerShell | , , , , ,


  1. Hello Martin, Thanks for posting this script – very useful for a VM Admin. I am new to scripting so will request you to extend this by adding mail functionality. Where do I add Send-MailMessage part? I played around a bit with trying to add this in If/Else but no luck. I would like script to mail with OR without snapshots on VMs. May you please help me with this? Thanks a bunch in advance.


    Comment by PC | April 18, 2013 | Reply

    • Pretty easy to do that, add this to the bottom of the script:

      Send-MailMessage -To “” -From “” -Subject “$VIServer Snapshot Report” -Body ($Report | Out-String) -BodyAsHtml -SmtpServer HostnameOrIPofYourSMTPrelayServer

      Comment by Martin9700 | April 18, 2013 | Reply

  2. Hi Martin, Thanks for a very useful script. Snapshots are the bane of a VM Admins life. I would like to add one thing to your script. I would like to add how many days the snapshot has been in existence. How would I go about that? Thanks again.

    Comment by John | June 12, 2013 | Reply

    • Glad you like it John. I’ve updated the script to add “Days Old” to the report, and while I was in there cleaned up a few other things including parameterizing the email settings. Should make the script a little easier to work with. Find the updated version here:

      Comment by Martin9700 | June 13, 2013 | Reply

      • Martin, Thanks so much. This really fits the bill for me. Thanks for making the mods and sharing.

        Comment by John | June 13, 2013

    • Glad to help, John!

      Comment by Martin9700 | June 13, 2013 | Reply

  3. Is it possible to run this script for multiple vCenter and combine the report as one?

    Comment by Hiro | January 15, 2015 | Reply

    • You could do a foreach loop through all the vcenter servers eg

      $vCenterServers = “Server1″,”Server2″,”Server3”

      foreach ($Server in $vCenterServers) {

      Connect-VIServer $Server

      $snapshots += get-vm |
      get-snapshot |
      where {$_.SizeGB -gt 0.99} |
      select vm,name,@{ Name=”size(GB)”;Expression={“{0:N1}” -f ( $_.sizeGB ) }},created,@{ Name=”VCenter Server”;Expression={$Server} }

      Disconnect-VIServer $Server -Force -Confirm:$false


      Comment by Alex | January 21, 2015 | Reply

  4. hello martin, i tried the script but fall into the try catch after the pssnapin

    “Just used Get-PSSnapin to see if the tool is loaded or not, if not go ahead and load the snap-in. Used Try/Catch to do some error checking and break out of the script if something goes wrong.”

    I am a newby.. can you help me with this error, how to solve it?
    Many thanks!

    Comment by Gonzalo | April 23, 2015 | Reply

  5. Can we get the report in excel format? Thanks

    Comment by Tri Diep | July 7, 2015 | Reply

    • $Report (before it’s converted to HTML with ConvertTo-HTML) has the data you want in it. Just use Export-CSV to create a CSV and then you can open that in Excel.

      Comment by Martin9700 | July 7, 2015 | Reply

  6. Nice thanks for this post ! Very useful.
    Just one thing that could help. Instead of using you GetCredentials function you can use the PowerCLI credential store, very easy and working great:

    Comment by Lucas | August 20, 2015 | Reply

  7. Hi Martin – I could not start the script at all. While using Windows Powershell to call the script it gives the error ‘No windows Powershell snap-ins matching the pattern ‘VMware.VimAutomation.Core” were found. However, if I do Get-PSSnapin it lists the Snap-in.

    If I call the script using PowerCLI 5.5 Release 1, getting the error as ‘Error Connecting to your vCenter Server because cannot find the path ‘HKLM:\software\vmware, Inc.\VMware vSphere\PowerCLI” because it does not exist. Whereas I’m sure PowerCLI is installed on this system.

    Please advise how to address these errors. Thanks.

    Comment by Uman | October 20, 2015 | Reply

    • running as admin should fix this

      Comment by Aaron Trentacosta | May 26, 2016 | Reply

  8. Excellent little script, could I ask for some advice. I would like to see any VMs that does NOT have a snapshot in this list also, maybe something along the lines of “NO SNAPSHOT TAKEN”. Is this possible ?


    Comment by Graham Alexander Paull | April 29, 2016 | Reply

  9. You’d have to do a fairly extensive rewrite of the script. The problem is it uses Get-VM (which gets all VM’s, a good start for you) but then does Get-SnapShot which will only return found snapshots. After that it creates the object for the report. You’d have to Get-VM and then manually loop through it and if no snapshot found create the object with the same fields in it, but report “No Snapshot” in one of the fields.

    Comment by Martin9700 | April 29, 2016 | Reply

  10. Can this be executed against a remote vcenter server? Let’s say I have a powershell/scripting server and I wanted to execute this script remotely.

    Comment by Joseph | June 27, 2017 | Reply

  11. Hi All, spent last few days on and off trying to get this to work correctly and being task schedule-able on powercli6.5 which uses the new ps1 and modules instead of console file. Had to drop a few things and enforce module loading, this will behave as original script and create same report. I’m sure it’s not perfect but I’ve not spending more time on it to make it better.

    Anyway, here’s a pastebin, enter the normal prefix url.


    To make it work in task schedule, make sure you set server execution to your server (i.e. 2012) run with highest privileges, and use action: powershell.exe -executionpolicy bypass -file “whatever.ps1”.

    Comment by Maciej Stolarczyk | March 15, 2018 | Reply

  12. Can you post powercli script for deleting mutiple VM servers snapshots ?

    Comment by Nathan | March 26, 2018 | Reply

  13. […] keep these in check and have a way to monitor your snapshots in your enviroment.  Take a look at this solution for querying and reporting snapshots in your environment, which you can then have sent via email as […]

    Pingback by Storage Admin Weekly Checklist - Virtualization Howto | January 11, 2021 | Reply

Leave a Reply to Nathan Cancel reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: