PowerCLI: Function for listing snapshots

My very first PowerCLI related post was about this same topic: listing snapshot info using PowerCLI.
In my original post (which you can see here) I only wrote a pretty simple one-liner. Which was kind of okay, but it was missing one crucial thing: who took the snapshot?

Why vmware hasn’t found a way to include a username in the get-snapshot cmdlet is something I just can’t understand. There’s really not much code needed to add this to the output, and there’s several ways of doing so.

I found that using Get-Snapshot and Get-VIEvent together was the easiest way to get all the info I want. It’s not a perfect solution, seeing as I really wanted to make use of the much faster Get-View instead of Get-Snapshot, but I have yet to figure out a good way to handle snapshot trees using Get-View.

As usual I created a function for this, Get-Snapshots:

function Get-Snapshots 
{
            [CmdletBinding()] 
            Param (
                [string]$VM = '*'
                  )
 
    $collection = @()
    Write-Progress -Activity "Finding snapshots..." -Status "This will tak a while, please wait" -PercentComplete 20 -Id 1 -ErrorAction SilentlyContinue
    $snapshots = Get-Snapshot -vm $VM
    Write-Progress -Activity "Finding snapshots..." -Status "Found all snapshots" -Completed -Id 1 -ErrorAction SilentlyContinue
 
    $progress = 1
    foreach ($snapshot in $snapshots) {
        Get-VIEvent -Start ($snapshot.Created).addminutes(-5) -Finish ($snapshot.Created).addminutes(5) -Entity $Snapshot.vm.name -Types info -maxsamples 20 | Where-Object {$_.FullFormattedMessage -like "*Create virtual machine snapshot*"} | ForEach-Object {
                Write-Progress -Activity "Finding snapshots" -Status "Working on $($_.Vm.Name)" -PercentComplete ($progress/$snapshots.count*100) -Id 1 -ErrorAction SilentlyContinue
                $object = New-Object PSObject
                Add-Member -InputObject $object NoteProperty VM $_.Vm.Name
                Add-Member -InputObject $object NoteProperty User $_.Username
                Add-Member -InputObject $object NoteProperty "Snapshot name" $Snapshot.Name
                Add-Member -InputObject $object NoteProperty "Snapshot description" $Snapshot.Description
                Add-Member -InputObject $object NoteProperty SizeGB ([math]::Round($Snapshot.SizeGB))
                Add-Member -InputObject $object NoteProperty Time $_.CreatedTime
                $collection += $object
                }
        $progress++
        }
 
    Write-Progress -Activity "Finding snapshots" -Status "All done" -Completed -Id 1 -ErrorAction SilentlyContinue
    $collection
 
    <#
     .Synopsis
      Lists snapshots in vCenter
     .Description
      List all snapshots in the entire vCenter
     .Example
      Get-Snapshots
      Lists all snapshots in the vCenter
     .Link
      http://cloud.kemta.net
     #>
}

You can run the function as it is, without any parameters, or you can specify which vm you want to get the snapshots of:

get-snapshots

As you can see, the output is a list. If you want it to be more readable for human eyes, I recommend piping it to Format-Table:

get-snapshots-ft

If you would rather run this as a script, instead of using the function, here’s the code for that:

    $collection = @()
    $snapshots = Get-Snapshot -vm *
 
    $progress = 1
    foreach ($snapshot in $snapshots) {
        Get-VIEvent -Start ($snapshot.Created).addminutes(-5) -Finish ($snapshot.Created).addminutes(5) -Entity $Snapshot.vm.name -Types info -maxsamples 20 | Where-Object {$_.FullFormattedMessage -like "*Create virtual machine snapshot*"} | ForEach-Object {
                Write-Progress -Activity "Finding snapshots" -Status "Working on $($_.Vm.Name)" -PercentComplete ($progress/$snapshots.count*100) -Id 1 -ErrorAction SilentlyContinue
                $object = New-Object PSObject
                Add-Member -InputObject $object NoteProperty VM $_.Vm.Name
                Add-Member -InputObject $object NoteProperty User $_.Username
                Add-Member -InputObject $object NoteProperty "Snapshot name" $Snapshot.Name
                Add-Member -InputObject $object NoteProperty "Snapshot description" $Snapshot.Description
                Add-Member -InputObject $object NoteProperty SizeGB ([math]::Round($Snapshot.SizeGB))
                Add-Member -InputObject $object NoteProperty Time $_.CreatedTime
                $collection += $object
                }
        $progress++
        }
 
    Write-Progress -Activity "Finding snapshots" -Status "All done" -Completed -Id 1 -ErrorAction SilentlyContinue
    $collection

The output, $collection, can be piped to Format-Table if you want a nice table of it:

get-snapshots-scripts

 

Leave a Reply

Your email address will not be published. Required fields are marked *