Snapshots or checkpoints in Hyper-V allow you to create point-in-time instances of where your virtual machine (VM) was including memory. Snapshots are great for quickly reverting changes to multiple points in time but, if not managed properly, can soon turn into a headache.

When a snapshot is taken, it creates a differencing disk with an .avhd(x) extension. As the VM continues running, this differencing disk grows so that it knows how to revert to that previous state if the time to restore comes. If you don't manage snapshots properly, you can soon find yourself without space. And due to the performance overhead snapshots incur, you may notice degradation in your VM's performance as well.

How do you prevent "snapshot/checkpoint sprawl"? Use PowerShell!

When a snapshot shows up in the Hyper-V console, you can normally find all snaps for a particular VM using the Get-VMSnapshot -VMName "<VMName>" command. After finding them, you can then pipe this checkpoint to Remove-VMSnapshot like Get-VMSnapshot ‑VMName <VMName> | Remove-VMSnapshot. Remove-VMSnapshot then removes the snapshot from the Hyper-V host. However, when a problem occurs during removal or upon removing the VM, you may end up with lingering checkpoint disk files not directly attached to a checkpoint anymore.

Finding checkpoints ^

To track down these lingering checkpoints, you'll first need to find the path storing all the Hyper-V checkpoints. To do this, you can use the Get-VmHost cmdlet. This cmdlet returns a property called VirtualHardDiskPath, which is the location where all the virtual hard disks (VHDs)—and thus diff disk checkpoints—are stored.

PS> $vhdPath = (Get-VMHost).VirtualHardDiskPath
PS> $vhdPath

Once I know the location of my checkpoints, I can then search for them in that folder. All diff disks created by checkpoints attached to a VM are in that VM's folder in the VHD path shown above. I can use Get-ChildItem to recurse through all files in the VHD path for files matching the .avhd(x) extension.

PS> $checkpointFiles = Get-ChildItem -Path $vhdPath -Filter ".avhd*" -Recurse
PS> $checkpointFiles
Finding snapshots

Finding snapshots

This information is helpful but not too user-friendly. I'd like to know which VM each checkpoint applies to, and I'd like to see the size in gigabytes rounded to the nearest gigabyte. Using a little PowerShell kung fu, I can get my script to return the name of the VM, the path to the checkpoint, when it was created, the last time it was written to, and its size.

$properties = @(
        'Name' = 'VMName';
        'Expression' = { $_.Name.Split('_')[0] }
        'Name' = 'Size (MB)'
        'Expression' = { [int]($_.Length/1GB) }
$checkPoints = $checkpointFiles | Select-Object -Property $properties

Limiting checkpoints to lingering ones ^

The above example pulls all differencing disks created by checkpoints, lingering or not. We only need to find the disks that don't have a VM. We'll need to find all the current VM names using the Get-VM cmdlet.

PS> $vmNames = (Get-VM).Name

Next, I'll need to limit the diff disks returned to those without a VM.

$lingeringCheckpointFiles = $checkPointFiles | Where-Object { $_.VMName ‑notin $vmNames }

The script above returns information about the lingering disks, which is helpful. But what if you want to take it to the next level and remove them? That's not a problem now that you have the code to find all of them. However, note that if a VM is actively reading/writing to the diff disk, you will need to shut down the VM to remove the disk.

Subscribe to 4sysops newsletter!

$lingeringCheckpointFiles | ForEach-Object {
    Remove-Item -Path $_.FullName

Summary ^

Using PowerShell, you can find where diff disks created by Hyper-V checkpoints are, how much space they're using, and what VMs they're attached to. Sometimes, diff disks created by checkpoints are left stranded without an attached VM. In such cases, we can use PowerShell to find all VMs and limit the diff disks returned to only those with existing VMs!

  1. Wayne Steel 3 years ago

    AVHDX files are not checkpoints. Everything in this article is wrong. You didn't even test that script, did you? Certainly not on a host with the default installation of PowerShell or where the VMs weren't in the default location or where they were created with a tool that doesn't put disk files in the default or, God forbid, where someone used a checkpoint as a way to test renaming a VM. PowerShell has real ways to match up checkpoints to their disk files and you skipped them all with hacked up nonsense.

    Lingering checkpoints are a real problem caused by backups not cleaning up after themselves, and literally nothing in here will help with that problem.

    Good job driving SEO traffic to your site with a completely junk article, though. /applause

  2. Leos Marek 3 years ago


    some things written are a bit odd. For example

    And due to the performance overhead snapshots incur, you may notice degradation in your VM's performance as well.

    This is obviously true only if the VM is actually writing/reading to the snapshot file. And in such case, you would not be able to remove it with described way, because the file would be locked. So the only way here would be to use standard snapshot commands. 

  3. Author
    Adam Bertram 3 years ago

    Updated some terminology, fixed an error in the script and inserted a note about removing diff disks with running VMs.

Leave a reply

Your email address will not be published.


© 4sysops 2006 - 2022


Please ask IT administration questions in the forums. Any other messages are welcome.


Log in with your credentials


Forgot your details?

Create Account