Introduction
Hyper-V Failover Clustering provides high availability for virtual machines — when a Hyper-V host fails, its VMs automatically restart on surviving hosts. This is essential for production workloads where downtime is unacceptable. This guide covers building a Hyper-V cluster from physical servers to running highly available VMs.
Prerequisites
- Minimum 2 servers (nodes) with Windows Server 2019/2022 Datacenter
- Shared storage: iSCSI SAN, Fibre Channel, or Storage Spaces Direct (S2D)
- Two network interfaces per node (production + cluster communication)
- All nodes domain-joined
Installing Hyper-V and Failover Clustering
POWERSHELL
# Run on ALL nodes
Install-WindowsFeature -Name Hyper-V, Failover-Clustering -IncludeManagementTools -Restart
# After restart: validate cluster configuration
Test-Cluster -Node "hv01.company.local", "hv02.company.local" `
-Include "Storage Spaces Direct", "Inventory", "Network", "System Configuration"
# Review the report! Fix any errors before creating cluster.Creating the Cluster
POWERSHELL
# Create cluster with static IP
New-Cluster `
-Name "HVCluster01" `
-Node "hv01.company.local", "hv02.company.local" `
-StaticAddress 192.168.1.20 `
-NoStorage # Add storage separately
# Configure cluster quorum
# For 2 nodes: need file share witness or Azure Cloud Witness
Set-ClusterQuorum -FileShareWitness "witness-serverhv-quorum"
# Verify cluster
Get-Cluster
Get-ClusterNodeConfiguring Cluster Networks
POWERSHELL
# Rename cluster networks for clarity
(Get-ClusterNetwork | Where-Object {$_.Address -eq "192.168.1.0"}).Name = "Production"
(Get-ClusterNetwork | Where-Object {$_.Address -eq "192.168.100.0"}).Name = "Cluster"
# Production network: allow client access
(Get-ClusterNetwork "Production").Role = 3 # 3 = Client+Cluster
# Cluster network: cluster communication only (not client traffic)
(Get-ClusterNetwork "Cluster").Role = 1 # 1 = Cluster onlyAdding Shared Storage
POWERSHELL
# Option A: iSCSI storage
# Connect to iSCSI target from each node first
Start-Service msiscsi
Set-Service msiscsi -StartupType Automatic
New-IscsiTargetPortal -TargetPortalAddress "192.168.100.50"
Connect-IscsiTarget -NodeAddress "iqn.2020-01.com.company:storage01"
# Initialize and format shared disk (run once, on one node)
Initialize-Disk -Number 1 -PartitionStyle GPT
New-Partition -DiskNumber 1 -UseMaximumSize -AssignDriveLetter
Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel "ClusterStorage"
# Add disk to cluster
Get-ClusterAvailableDisk | Add-ClusterDisk
# Option B: Storage Spaces Direct (S2D)
Enable-ClusterStorageSpacesDirect -CacheState Disabled
# Create virtual disk on S2D
New-Volume -StoragePoolFriendlyName "S2D on HVCluster01" `
-FriendlyName "VMs-Volume01" `
-FileSystem CSVFS_ReFS `
-StorageTierFriendlyNames Performance, Capacity `
-StorageTierSizes 100GB, 500GBCreating Highly Available VMs
POWERSHELL
# Create VM on cluster shared volume
$VMPath = "C:ClusterStorageVMs-Volume01"
New-VM `
-Name "WebServer01" `
-MemoryStartupBytes 4GB `
-VHDPath "$VMPathWebServer01WebServer01.vhdx" `
-NewVHDSizeBytes 80GB `
-SwitchName "Production" `
-Path "$VMPath"
# Configure VM
Set-VM -Name "WebServer01" `
-ProcessorCount 4 `
-DynamicMemory $true `
-MemoryMinimumBytes 2GB `
-MemoryMaximumBytes 16GB
# Make VM highly available
Add-ClusterVirtualMachineRole -VMName "WebServer01"
# Verify HA status
Get-ClusterGroup "WebServer01"Live Migration
POWERSHELL
# Move VM to specific node (no downtime)
Move-ClusterVirtualMachineRole `
-Name "WebServer01" `
-Node "hv02.company.local" `
-MigrationType Live
# Drain a node for maintenance
Suspend-ClusterNode -Name "hv01.company.local" -Drain
# After maintenance: resume
Resume-ClusterNode -Name "hv01.company.local"Monitoring Cluster Health
POWERSHELL
# Overall cluster status
Get-ClusterNode | Select-Object Name, State, NodeWeight
Get-ClusterGroup | Select-Object Name, OwnerNode, State
# Check for cluster events
Get-ClusterLog -Destination C:Logs
# VM placement report
Get-ClusterGroup | Where-Object {$_.GroupType -eq "VirtualMachine"} |
Select-Object Name, OwnerNode, State |
Sort-Object OwnerNode
# Disk health
Get-PhysicalDisk | Select-Object FriendlyName, HealthStatus, OperationalStatus, SizeAutomated VM Balancing
POWERSHELL
# Enable VM load balancing (auto-migrate VMs for even distribution)
(Get-Cluster).AutoBalancerMode = 2 # 2 = Balance when node joins
(Get-Cluster).AutoBalancerLevel = 1 # 1 = Low aggressiveness
# Anti-affinity (keep VMs on different nodes)
# Useful to prevent all web servers landing on same host
New-ClusterAffinityRule -Name "WebServers-AntiAffinity" -Ruletype SameFaultDomain
Add-ClusterGroupToAffinityRule -Name "WebServers-AntiAffinity" -Groups "WebServer01", "WebServer02"Hyper-V clustering transforms individual servers into a resilient platform where VMs can survive host failures. The most important skills: understanding quorum (the mechanism that prevents split-brain), mastering Live Migration for maintenance, and knowing how to drain nodes gracefully.
