Introduction to Hyper-V Live Migration on Windows Server 2019
Live Migration moves a running virtual machine from one Hyper-V host to another with zero downtime — the VM continues running throughout the move, and users experience no interruption. This is essential for host maintenance (patching, hardware replacement), workload balancing across a cluster, and responding to hardware failures. Windows Server 2019 Hyper-V supports Live Migration both within a Failover Cluster (using shared storage) and outside a cluster (using Shared Nothing Live Migration, which moves both the VM and its storage simultaneously). This guide covers configuring, optimising, and troubleshooting Hyper-V Live Migration in detail.
Live Migration Prerequisites
For Live Migration to work, both source and destination hosts must meet these requirements:
– Both hosts must have compatible CPU features (same vendor — Intel to Intel or AMD to AMD — and compatible instruction set). Use CPU compatibility mode if migrating between different processor generations.
– Both hosts must be running Windows Server 2019 Hyper-V (or a supported combination with Server 2016).
– Both hosts must be domain-joined to the same domain (for Kerberos constrained delegation) or configured for certificate-based auth.
– Network connectivity between hosts (dedicated migration network recommended).
# Check CPU compatibility between source and destination
(Get-VMHost).ProcessorVendorName # Run on both hosts — must match (GenuineIntel/AuthenticAMD)
# Check Hyper-V version
(Get-VMHost).HyperVVersion
# Check processor features
Get-WmiObject -Class Win32_Processor |
Select-Object Name, NumberOfCores, VirtualizationFirmwareEnabled | Format-Table
Enable Live Migration on Both Hosts
# Enable Live Migration with Kerberos authentication
Enable-VMMigration
# Configure Live Migration settings
Set-VMHost `
-VirtualMachineMigrationEnabled $true `
-VirtualMachineMigrationAuthenticationType Kerberos `
-MaximumVirtualMachineMigrations 4 ` # Max simultaneous live migrations
-MaximumStorageMigrations 2 # Max simultaneous storage migrations
# Verify configuration
Get-VMHost | Select-Object VirtualMachineMigrationEnabled,
VirtualMachineMigrationAuthenticationType,
MaximumVirtualMachineMigrations | Format-List
Configure Kerberos Constrained Delegation
For Kerberos authentication to work in Live Migration, both Hyper-V host computer accounts must be trusted for delegation to the Microsoft Virtual System Migration Service on each other. This is configured in Active Directory:
# Run on a Domain Controller with RSAT Active Directory module
# Configure constrained delegation for HyperV-Host1 to migrate to HyperV-Host2
$host1 = Get-ADComputer "HYPERV-HOST1"
$host2 = Get-ADComputer "HYPERV-HOST2"
# Allow Host1 to delegate to Host2's migration service
Set-ADComputer "HYPERV-HOST1" -Add @{
"msDS-AllowedToDelegateTo" = @(
"Microsoft Virtual System Migration Service/$($host2.DNSHostName)",
"cifs/$($host2.DNSHostName)",
"Microsoft Virtual System Migration Service/$($host2.Name)",
"cifs/$($host2.Name)"
)
}
Set-ADAccountControl "HYPERV-HOST1" -TrustedForDelegation $false
Set-ADAccountControl "HYPERV-HOST1" -TrustedToAuthForDelegation $true
# Repeat symmetrically for Host2 to migrate to Host1
Set-ADComputer "HYPERV-HOST2" -Add @{
"msDS-AllowedToDelegateTo" = @(
"Microsoft Virtual System Migration Service/$($host1.DNSHostName)",
"cifs/$($host1.DNSHostName)",
"Microsoft Virtual System Migration Service/$($host1.Name)",
"cifs/$($host1.Name)"
)
}
Set-ADAccountControl "HYPERV-HOST2" -TrustedToAuthForDelegation $true
Configure Dedicated Migration Network
Live Migration generates significant network traffic (the entire VM memory must be transferred). Dedicate a separate network interface for migration to avoid impacting production VM traffic:
# Add a dedicated migration network (must be configured on both hosts)
Add-VMMigrationNetwork -IP "10.10.10.1" -Subnet "255.255.255.0" -Priority 1
# Verify migration networks
Get-VMMigrationNetwork
# Remove a migration network if reconfiguring
Remove-VMMigrationNetwork -IP "10.10.10.1"
# Configure migration to prefer the dedicated network
Set-VMHost -VirtualMachineMigrationEnabled $true
Add-VMMigrationNetwork -IP "10.10.10.1" -Subnet "255.255.255.0" -Priority 1
Add-VMMigrationNetwork -IP "192.168.1.10" -Subnet "255.255.255.0" -Priority 2 # Fallback
Perform a Live Migration
# Live migrate a VM to another host (VM stays running, shared storage assumed)
Move-VM -Name "WebServer01" -DestinationHost "hyperv-host2.corp.example.com"
# Live migrate with specific destination path for VM configuration file
Move-VM -Name "WebServer01" `
-DestinationHost "hyperv-host2.corp.example.com" `
-DestinationStoragePath "D:HyperVVMs"
# Monitor migration progress
Get-VM -Name "WebServer01" | Select-Object Name, State, Status | Format-List
# Status will show "Migrating" during the operation
Shared Nothing Live Migration (Move VM and Storage Simultaneously)
Shared Nothing Live Migration (SNLM) moves both the running VM and its VHD/VHDX files from one host to another in a single operation, with no shared storage required. This is used when both hosts have local storage and no SAN:
# Shared Nothing Live Migration — moves VM config, checkpoints, and all VHDs
Move-VM -Name "WebServer01" `
-DestinationHost "hyperv-host2.corp.example.com" `
-IncludeStorage `
-DestinationStoragePath "D:HyperVVMsWebServer01"
# Or use VHD migration paths to control where each disk goes
Move-VM -Name "WebServer01" `
-DestinationHost "hyperv-host2.corp.example.com" `
-Vhds @(
@{SourceFilePath="C:HyperVWebServer01WebServer01-OS.vhdx";
DestinationFilePath="D:HyperVWebServer01WebServer01-OS.vhdx"},
@{SourceFilePath="C:HyperVWebServer01WebServer01-Data.vhdx";
DestinationFilePath="E:HyperVDataWebServer01-Data.vhdx"}
)
Enable CPU Compatibility Mode
When migrating between hosts with different processor generations (e.g., Intel Broadwell to Intel Skylake), enable CPU compatibility mode on the VM to mask new instructions that the older host doesn’t support:
# Enable processor compatibility (VM must be OFF to change this)
Set-VMProcessor -VMName "WebServer01" -CompatibilityForMigrationEnabled $true
# Verify
Get-VMProcessor -VMName "WebServer01" |
Select-Object VMName, CompatibilityForMigrationEnabled | Format-Table
# Note: CPU compatibility reduces available processor features slightly
# but enables migration between processor generations
Configure Live Migration in a Failover Cluster
# In a Hyper-V cluster, use Quick Migration or Live Migration via Failover Cluster Manager
# Move a clustered VM between nodes using Live Migration
Get-ClusterGroup | Where-Object GroupType -eq "VirtualMachine"
# Move specific VM cluster resource
Move-ClusterVirtualMachineRole -Name "WebServer01" -Node "HYPERV-HOST2" -MigrationType Live
# Set default migration type for the cluster
(Get-Cluster).DefaultFlowMigration = $true
# Configure Live Migration settings per cluster
Get-ClusterResourceType -Name "Virtual Machine" |
Set-ClusterResourceType -DefaultTimeout 30
Monitor and Troubleshoot Live Migration
# Monitor ongoing migrations
Get-VM * | Where-Object Status -like "*Migrating*" |
Select-Object Name, Status, ComputerName | Format-Table
# Check Hyper-V event log for migration events
Get-WinEvent -LogName "Microsoft-Windows-Hyper-V-VMMS-Admin" |
Where-Object { $_.Message -match "live migration" -or $_.Id -in @(20302,20303,20304) } |
Select-Object TimeCreated, Id, Message | Format-List
# Test if Live Migration will succeed (dry run)
# Check network connectivity to destination on migration ports
Test-NetConnection -ComputerName "hyperv-host2.corp.example.com" -Port 6600
Test-NetConnection -ComputerName "hyperv-host2.corp.example.com" -Port 443
Summary
# In a Hyper-V cluster, use Quick Migration or Live Migration via Failover Cluster Manager
# Move a clustered VM between nodes using Live Migration
Get-ClusterGroup | Where-Object GroupType -eq "VirtualMachine"
# Move specific VM cluster resource
Move-ClusterVirtualMachineRole -Name "WebServer01" -Node "HYPERV-HOST2" -MigrationType Live
# Set default migration type for the cluster
(Get-Cluster).DefaultFlowMigration = $true
# Configure Live Migration settings per cluster
Get-ClusterResourceType -Name "Virtual Machine" |
Set-ClusterResourceType -DefaultTimeout 30# Monitor ongoing migrations
Get-VM * | Where-Object Status -like "*Migrating*" |
Select-Object Name, Status, ComputerName | Format-Table
# Check Hyper-V event log for migration events
Get-WinEvent -LogName "Microsoft-Windows-Hyper-V-VMMS-Admin" |
Where-Object { $_.Message -match "live migration" -or $_.Id -in @(20302,20303,20304) } |
Select-Object TimeCreated, Id, Message | Format-List
# Test if Live Migration will succeed (dry run)
# Check network connectivity to destination on migration ports
Test-NetConnection -ComputerName "hyperv-host2.corp.example.com" -Port 6600
Test-NetConnection -ComputerName "hyperv-host2.corp.example.com" -Port 443Hyper-V Live Migration on Windows Server 2019 provides seamless VM mobility with zero downtime. Successful deployment requires compatible CPUs, Kerberos constrained delegation in Active Directory, a dedicated migration network to avoid impacting production traffic, and appropriate storage paths on the destination host. For environments without shared storage, Shared Nothing Live Migration moves both the VM state and its VHD files simultaneously. CPU compatibility mode enables migration across processor generations when needed. Combined with Failover Clustering, Live Migration forms the foundation of highly available Hyper-V infrastructure.