The greatest challenge to any thinker is stating the problem in a way that will allow a solution

Bertrand Russell


On 12 Aug 2011

PowerCLI, VMware

Tags: , ,

The ability to snapshot a VM is wondrous thing; the ability for a snapshot to be forgotten, eat up all all your storage or grow so large that you can’t remove it without causing impact is not so wondrous.

How you manage snapshots is up to, but unless you routinely tidy them up (especially if you use some thing that utilises snapshots like vRanger, which can occasionally leave them behind), they will cause you a problem at some point.  And sod’s law dictates that the problem occurs to important VM, when you haven’t the time to spare.

You can set up a vCentre alarm as described in this VMware KB article, but it can a bit of a blunt tool, and doesn’t allow you to enforce a general policy such “we only allow snapshots to run for 48hrs”.

Instead I opted to create script that I run on every few days to generate a report…

$OutputFile = "VM-Snapshot.csv"
function Log ($text) {
    [int]$duration = (New-TimeSpan $start (Get-Date)).TotalSeconds
    Write-Host "$duration secs | $text"
function Log-NoNewLine ($text) {
    [int]$duration = (New-TimeSpan $start (Get-Date)).TotalSeconds
    Write-Host "$duration secs | $text" -nonewline
$start = Get-Date
$table = New-Object system.Data.DataTable "Results"
$table.columns.add((New-Object system.Data.DataColumn Name,([string])))
$table.columns.add((New-Object system.Data.DataColumn Folder,([string])))
$table.columns.add((New-Object system.Data.DataColumn Snap,([string])))
$table.columns.add((New-Object system.Data.DataColumn Created,([datetime])))
$table.columns.add((New-Object system.Data.DataColumn Size_MB,([single])))
$table.columns.add((New-Object system.Data.DataColumn PowerState,([string])))
Log("Getting list of VMs to check...")
$VMs = Get-VM | Where {$_.PowerState -eq "PoweredOn"} | Sort -Property Name
Log ("Got list of " + ($VMs.Count) + " VMs to check")
$VMno = 0
$VMtot = $VMs.Count
foreach ($vm in $VMs) {
    $VMno = $VMno + 1
    Log-NoNewLine "[$VMno/$VMtot] $vm - "
    $Snaps = Get-Snapshot -VM $vm
    if ($Snaps) {
        foreach ($snap in $snaps) {
            $row = $table.NewRow()
            $row.Name = $vm.Name 
            $row.Folder = Get-Folder -Id $vm.FolderId
            $row.Snap = $snap.Name
            $row.Created = $snap.Created
            $row.Size_MB = $snap.SizeMB
            $row.PowerState = $snap.PowerState
            Write-Host $row.Snap "| Created" $row.Created "| Size" $row.Size_MB "MB | " $row.PowerState
    } else {
        Write-Host "No snapshot"
if ($table.rows.Count) {
    Log "Completed, writing out table..."
    $table | Format-Table
    $table | Export-Csv -path $OutputFile
    #Send via email
    $smtp = New-Object Net.Mail.SmtpClient -arg "smtpserver"
    $msg = New-Object Net.Mail.MailMessage
    $attach = New-Object Net.Mail.Attachment($OutputFile)
    $msg.From = "from"
    $msg.To.Add = "to"
    $msg.Subject = "Snapshots found running!!"
    $msg.Body = "$table.rows.Count snapshots found to be running, see attachment for further info"
Log "Completed!"

Be aware that there’s a bug in the way Get-Snapshot handles VM’s in VI4, in that for the snapshot size it tends to report the maximum size a snapshot file could become, not the actual size that it is. As a result there is a workaround to found here – I’ve found that this reports smaller sizes for VI3 snapshots as well (which match the actual disk usage in the few occasions I’ve bothered to check).

To implement the Get-Snapshot size bug, download the workaround file from the link above. I’ve placed it in a sub-folder called lib, then I’ve included it into my main script by using…

. .libgetsnapshotsize-1.ps1

…then I’ve just replaced Get-Snapshot with CalculateVMSnapshotsSizeMB

Leave a Reply

XHTML: You can use these tags if you know what they are: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

ERROR: si-captcha.php plugin says GD image support not detected in PHP!

Contact your web host and ask them why GD image support is not enabled for PHP.

ERROR: si-captcha.php plugin says imagepng function not detected in PHP!

Contact your web host and ask them why imagepng function is not enabled for PHP.