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:

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:

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: