Introduction to Hyper-V Checkpoints on Windows Server 2019
Hyper-V Checkpoints (formerly called Snapshots) capture the state of a running virtual machine at a specific point in time, allowing you to revert the VM to that state if needed. This is invaluable before applying updates, making configuration changes, testing software installations, or performing any risky operation. Windows Server 2019 introduces two checkpoint types with distinct behaviours: Standard Checkpoints and Production Checkpoints. Understanding when to use each type, how to manage checkpoint chains, and how checkpoints impact performance and storage is essential for safe Hyper-V operations.
Standard Checkpoints vs Production Checkpoints
Standard Checkpoints (formerly Snapshots): Capture the complete VM state — memory, processor state, and disk changes. The VM can be reverted to exactly the state it was in when the checkpoint was taken, including the state of running applications and in-flight transactions. Not suitable for production use because restoring a standard checkpoint can leave applications in an inconsistent state (e.g., a database mid-transaction).
Production Checkpoints: Use the Volume Shadow Copy Service (VSS) inside the guest OS to create an application-consistent checkpoint. Memory state is NOT captured. The VM is quiesced at the application level before the checkpoint, ensuring databases and applications are in a consistent state. Suitable for production VMs. This is the default in Windows Server 2019.
# Check current checkpoint type setting for a VM
Get-VM -Name "WebServer01" | Select-Object Name, CheckpointType | Format-List
# Checkpoint types:
# Standard - Legacy snapshot behaviour (memory + disk)
# Production - VSS-based, no memory capture (default)
# ProductionOnly - Production checkpoints only; fails if VSS can't quiesce
# Disabled - Checkpoints are not allowed on this VM
Configure Checkpoint Type
# Set to Production checkpoints (recommended for production VMs)
Set-VM -Name "WebServer01" -CheckpointType Production
# Set to Standard checkpoints (use for dev/test or when VSS is not available)
Set-VM -Name "DevVM01" -CheckpointType Standard
# Disable checkpoints entirely (for high-performance production VMs)
Set-VM -Name "DatabaseVM" -CheckpointType Disabled
# For domain-joined VMs, ProductionOnly ensures only VSS-consistent checkpoints succeed
Set-VM -Name "ExchangeVM" -CheckpointType ProductionOnly
# Bulk set all VMs to Production checkpoints
Get-VM | Set-VM -CheckpointType Production
Create Checkpoints
# Create a checkpoint of a running VM (VM stays running)
Checkpoint-VM -Name "WebServer01" -SnapshotName "Pre-patch June 2026"
# Create a checkpoint with automatic timestamp name
Checkpoint-VM -Name "WebServer01"
# Create checkpoints for multiple VMs before a maintenance window
$vmsToCheckpoint = @("WebServer01","WebServer02","AppServer01")
foreach ($vm in $vmsToCheckpoint) {
$snapName = "Pre-maintenance $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
Write-Host "Creating checkpoint for $vm..."
Checkpoint-VM -Name $vm -SnapshotName $snapName
Write-Host " Done: $snapName"
}
List and Inspect Checkpoints
# List all checkpoints for a VM
Get-VMSnapshot -VMName "WebServer01" |
Select-Object Name, SnapshotType, CreationTime, ParentSnapshotName | Format-Table
# List checkpoints for all VMs
Get-VMSnapshot * |
Select-Object VMName, Name, SnapshotType, CreationTime |
Sort-Object VMName, CreationTime | Format-Table
# Get checkpoint size information (approximate disk usage)
Get-VMSnapshot -VMName "WebServer01" | ForEach-Object {
$avhdxFiles = Get-ChildItem -Path (Get-VM -Name "WebServer01").SnapshotFileLocation `
-Filter "*.avhdx" -ErrorAction SilentlyContinue
Write-Host "$($_.Name): Checkpoint files found"
}
Revert to a Checkpoint
Reverting to a checkpoint returns the VM to the exact state captured in that checkpoint. The VM is stopped, state is restored, and the VM can be started again. Any changes made to the VM after the checkpoint was taken are lost:
# Revert to the most recent checkpoint (automatic restore point)
# The VM must be stopped or the cmdlet will stop it automatically
Restore-VMSnapshot -VMName "WebServer01" -Name "Pre-patch June 2026" -Confirm:$false
# After restoring, start the VM
Start-VM -Name "WebServer01"
# Revert to parent checkpoint (go back one step in checkpoint chain)
$snapshot = Get-VMSnapshot -VMName "WebServer01" |
Sort-Object CreationTime -Descending | Select-Object -First 1
Restore-VMSnapshot -VMSnapshot $snapshot -Confirm:$false
Delete Checkpoints
Checkpoints consume significant disk space because differential disks (AVHDX files) grow as changes accumulate. After confirming changes are good, delete checkpoints to merge the differential disk back into the parent VHD and reclaim space:
# Delete a specific checkpoint by name
Remove-VMSnapshot -VMName "WebServer01" -Name "Pre-patch June 2026"
# Delete all checkpoints for a VM (merges all differencing disks)
Remove-VMSnapshot -VMName "WebServer01" -IncludeAllChildSnapshots
# Delete checkpoints older than 7 days
$cutoff = (Get-Date).AddDays(-7)
Get-VMSnapshot * | Where-Object CreationTime -lt $cutoff | ForEach-Object {
Write-Host "Deleting checkpoint: $($_.VMName) - $($_.Name) - $($_.CreationTime)"
Remove-VMSnapshot -VMName $_.VMName -Name $_.Name
}
# WARNING: Deleting a checkpoint triggers a merge operation
# The VM continues running but VHDX merge runs in the background
# Monitor merge completion before taking new checkpoints
Get-VM -Name "WebServer01" | Select-Object Name, Status
Checkpoint Storage Impact and Performance
Each checkpoint creates a differencing disk (AVHDX file) that records changes made to the VM’s disks after the checkpoint was taken. The original VHDX becomes read-only, and all new writes go to the AVHDX. This can significantly impact storage performance:
# Check disk space used by checkpoint files
$vmSnapshotPath = (Get-VM -Name "WebServer01").SnapshotFileLocation
$checkpointFiles = Get-ChildItem -Path $vmSnapshotPath -Recurse -Include "*.avhdx","*.vsv","*.vmrs"
$totalSizeMB = ($checkpointFiles | Measure-Object Length -Sum).Sum / 1MB
Write-Host "Checkpoint storage used: $([math]::Round($totalSizeMB, 0)) MB"
$checkpointFiles | Select-Object Name, @{n="SizeMB";e={[math]::Round($_.Length/1MB,1)}} | Format-Table
# Check checkpoint chain depth (deep chains degrade performance significantly)
$depth = 0
$current = Get-VMSnapshot -VMName "WebServer01" | Sort-Object CreationTime -Descending | Select-Object -First 1
while ($current -and $current.ParentSnapshotName) {
$depth++
$current = Get-VMSnapshot -VMName "WebServer01" | Where-Object Name -eq $current.ParentSnapshotName
}
Write-Host "Checkpoint chain depth: $depth"
if ($depth -gt 5) { Write-Warning "Deep checkpoint chains significantly degrade I/O performance!" }
Export VM with Checkpoints
Exporting a VM captures the complete VM including all checkpoint history:
# Export VM with all checkpoints to a folder
Export-VM -Name "WebServer01" -Path "D:VMBackups"
# Export a specific checkpoint (creates a new VM from that checkpoint state)
$snap = Get-VMSnapshot -VMName "WebServer01" -Name "Pre-patch June 2026"
Export-VMSnapshot -VMSnapshot $snap -Path "D:VMBackupsWebServer01-prepatch"
Automate Checkpoint Management
# Scheduled checkpoint script — create pre-maintenance and clean up old ones
$vms = Get-VM | Where-Object State -eq Running
$snapName = "Scheduled $(Get-Date -Format 'yyyy-MM-dd HH:mm')"
foreach ($vm in $vms) {
# Create new checkpoint
Checkpoint-VM -Name $vm.Name -SnapshotName $snapName
# Remove checkpoints older than 48 hours for this VM
Get-VMSnapshot -VMName $vm.Name |
Where-Object CreationTime -lt (Get-Date).AddHours(-48) |
ForEach-Object { Remove-VMSnapshot -VMName $vm.Name -Name $_.Name }
}
# Log checkpoint creation
Write-EventLog -LogName Application `
-Source "Hyper-V Checkpoint Manager" `
-EventId 9001 `
-Message "Created scheduled checkpoints for $($vms.Count) VMs: $snapName"
Best Practices for Production Checkpoints
Key guidelines for managing Hyper-V checkpoints safely in production:
# 1. Use Production checkpoint type for all production VMs
Get-VM | Where-Object CheckpointType -ne "Production" | Format-Table Name, CheckpointType
# 2. Keep checkpoint chains shallow (max 3-5 checkpoints per VM)
# 3. Delete checkpoints promptly after confirming changes
# 4. Never leave checkpoints in place for more than 24 hours on active VMs
# 5. Monitor AVHDX growth with scheduled task:
Get-VM | ForEach-Object {
$snapCount = (Get-VMSnapshot -VMName $_.Name -ErrorAction SilentlyContinue | Measure-Object).Count
if ($snapCount -gt 3) {
Write-Warning "$($_.Name) has $snapCount checkpoints — consider cleaning up!"
}
}
Summary
Hyper-V Checkpoints on Windows Server 2019 are a powerful tool for risk management before changes, but require disciplined management. Always use Production Checkpoints for production VMs to leverage VSS application consistency. Keep checkpoint chains short — deep chains significantly degrade VM storage I/O performance. Delete checkpoints promptly after confirming that applied changes are stable. Automate checkpoint cleanup with scheduled tasks to prevent accidental accumulation. For backup purposes, use dedicated Hyper-V backup solutions (Windows Server Backup or third-party) rather than long-lived checkpoints, as checkpoints are not a substitute for proper backup strategies.