PowerShell Friday: Snapshots

Virtual machine snapshots are useful for sysadmins, since they  preserve the state of a virtual machine’s virtual disk and, optionally, virtual memory before upgrading an application for example. VM Snapshots are also taken by a lot of backup applications for VMs at the start of the backup and then removed at the end of the backup. Since the original vmdk is frozen and all changes are written to the snapshotfile it can get big real fast, especially on machines that do a lot of write actions. Next to the size there is also a performance component to the use of snapshots. That’s why it is wise to manage your snapshots on a regular basis.

Getting the snapshots

Before we can check out which VMs have snapshots we need to connect to the vCenter server as I described in a previous article. After that to get a list of VMs so we can pipe them to the Get-Snapshot cmdlet to get information about the snaphots.

$snapshots = Get-VM -Server $vc | Get-Snapshot

If we only do this we have a list of snapshots without any context to the VMs they belong to. To get a list (table) we can use the following command:

Get-VM | Get-Snapshot | Select VM,Created,Name,SizeMB | FT

Now we get a list of VMs, with descriptions, size and the date created. The next line will get all VMs where the snapshots are older than 7 days.

Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-7)} | Select-Object VM, Name, Created, SizeMB

There are a lot of PowerCLI scripts out there that can help you with your snapshot management, but I would recommend to get familiar with managing snapshots with PowerCLI before you use someone’s PowerCLI script.

Deleting the snapshots

if you want to delete all snapshots for a specific VM you can use:

Get-VM -Name MyVM | Get-Snapshot | Remove-Snapshot

You get a prompt if you are Ok with this.

Sometimes you just want to remove one snapshot. Then you use the name of the snapshot:

Get-VM -Name MyVM | Get-Snapshot -Name TheNameOfTheSnapshot | Remove-Snapshot

The same goes when you want to delete snapshots older than 7 days.

Get-VM | Get-Snapshot | Where {$_.Created -lt (Get-Date).AddDays(-7)} | Remove-Snapshot

Consolidation

Sometimes you get a “Virtual machine disks consolidation is needed” Configuration Issue warning in the Summary tab. When you initiate a Delete or DeleteAll operation on snapshots, the snapshot is immediately deleted from Snapshot Manager, after that the  .vmdk files are consolidated on-disk. If the consolidation fails for some reason, it happens that the (snapshot) vmdk’s may remain on disk and/or be actively used on the Datastore. To resolve that you can use the consolidation cmdlet in PowerCLI:

Get-VM | Where-Object {$_.Extensiondata.Runtime.ConsolidationNeeded}

This line shows which VMs need consolidations. With the same ease we can consolidate all the VMs that need this.

Get-VM | Where-Object {$_.Extensiondata.Runtime.ConsolidationNeeded} | foreach {$_.ExtensionData.ConsolidateVMDisks_Task()}

Creating snapshots

If you don’t want to delete snapshots from somebody else (or the GUI) you can create your own snapshots with PowerCLI.

New-Snapshot -VM MyVM -Name BeforeUpdate

or in the pipeline:

Get-VM -Name MyVM | New-Snapshot -Name BeforePatch

If you really, really, really want to make your life easier: Use the Description parameter so you can give some extra info on why you created the snapshot and when it can be deleted. You could even go as far as using the description field for extra parameters like when to delete the snapshot.

Better one backup too often, than….

As always, if you change or delete something, make sure you know what you are doing and try to think if a backup is a wise precaution.