- Create a certificate-signed RDP shortcut via Group Policy - Fri, Aug 9 2019
- Monitor web server uptime with a PowerShell script - Tue, Aug 6 2019
- How to build a PowerShell inventory script for Windows Servers - Fri, Aug 2 2019
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 C:\Lab\VHDs
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
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] } }, Fullname, CreationTime, LastWriteTime, @{ 'Name' = 'Size (MB)' 'Expression' = { [int]($_.Length/1GB) } } ) $checkPoints = $checkpointFiles | Select-Object -Property $properties $checkPoints
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!
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
Adam,
some things written are a bit odd. For example
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.
Updated some terminology, fixed an error in the script and inserted a note about removing diff disks with running VMs.