PowerCLI: Speed boost, Find VM Snapshots by Name.

I use NetApp SnapManager for Virtual Infrastructure(SMVI) to back up 95% of my environment. SMVI isn’t perfect, and it’s kinda a pain, but it gives me the ability to back up 100-250 vm’s in less than 10min! Well the actual NetApp snapshot takes seconds. The rest of the time is spent waiting on ESX snapshots. The only real downside here is from time to time SMVI will fail to delete the ESX snapshots. I have been using PowerCLI to find and delete these snapshot, but the cmdlets are just too slow, for what I’m trying to do. I’ll post my Finalized SMVI cleanup script later. Until then, I give you finding snapshots really fast!

To start with the traditional PowerCLI cmdline. Simple, powerful, and intuitive, but all those things at a price. All Times based on a small farm 8 ESX hosts 100+ VM’s.

Example: Execution Time(108 Seconds)

$SMVISnapshots = Get-VM | Get-Snapshot -Name smvi*

That’s just not fast enough for me. I’m looking for a specific snapshot in every VM. To scale this I knew I needed to dig in to the SDK. I decided to break the problem down into two steps.
1. Find any vm with a snapshot.
2. Filter the snapshots on those vm’s by Name.

Step one turned out to be real easy, and scary fast!

Example: Execution Time(0.103 Seconds)

#Get all VirtualMachines with snapshots
$AllSnapShots = Get-View -ViewType virtualmachine -Property snapshot `
    -Filter @{"Snapshot"="VMware.Vim.VirtualMachineSnapshotInfo"}

You’re eyes aren’t deceiving you that’s a 103 milliseconds! Don’t get too excited though because we still have to filter this data. The Get-Snapshot CmdLet did all this work for us before. By leveraging Get-View I gained performance, at the cost of increased complexity… The real performance boost comes from only tasking the property collector with a single property to return. to put this in perspective Get-VM returns hundreds by default.

Step two; have I mentioned how much I love Advanced Functions!

There really isn’t anything fancy In that function… well except for the fact that it’s fast as all get out!

Example: Execution Time(0.161 Seconds)

$Snaps = Get-View -ViewType virtualmachine -Property snapshot `
    -Filter @{"Snapshot"="VMware.Vim.VirtualMachineSnapshotInfo"} | Get-Snapinfo

Example: Execution Time(0.187 Seconds)

$Snaps = Get-View -ViewType virtualmachine -Property snapshot `
    -Filter @{"Snapshot"="VMware.Vim.VirtualMachineSnapshotInfo"} | Get-Snapinfo -Filter "^smvi_"

the result:
Get-Snapinfo_Results
Note: the Output shown above, reports a total execution time of 332ms the additional 100ms can be tracked back to PowerShell actually writing the output to the host.

There you have it, I can now find any snapshot by name in milliseconds, how cool is that! On a side note; I hope I’ve driven the point home that PowerCLI is actually quite fast given the amount of work it does. When I develop these one off solutions I increase the performance only because I limit the scope of work! Something to keep in mind if you’re trying to speed up a script, the SDK isn’t any faster, it just allows you to be more targeted.

~Glenn