How to Configure Windows Server 2019 for High Availability
High Availability (HA) in Windows Server 2019 is achieved through multiple technologies that eliminate single points of failure. The primary HA technologies include Failover Clustering for automatic failover of roles and virtual machines, Network Load Balancing for distributing workloads across multiple servers, Always On Availability Groups for SQL Server databases, and redundant hardware configurations at the network, storage, and power levels. This guide covers the planning, architecture, and configuration of high availability features in Windows Server 2019.
High Availability Architecture Planning
Before configuring HA features, identify your service requirements. Determine the Recovery Time Objective (RTO: how quickly the service must recover) and Recovery Point Objective (RPO: how much data loss is acceptable). These determine which HA technology is appropriate. Also identify all single points of failure: single switches, single power feeds, single storage controllers, single servers. Address each layer systematically.
Network Redundancy with NIC Teaming
NIC Teaming (LBFO – Load Balancing and Failover) combines multiple network adapters into a single logical interface, providing bandwidth aggregation and fault tolerance at the network adapter level:
# View available network adapters
Get-NetAdapter | Select-Object Name, InterfaceDescription, Status, LinkSpeed
# Create a NIC team with two adapters (switch-independent mode for single switch)
New-NetLbfoTeam `
-Name "ProductionTeam" `
-TeamMembers "Ethernet", "Ethernet 2" `
-TeamingMode SwitchIndependent `
-LoadBalancingAlgorithm TransportPorts `
-Confirm:$false
# Create a team with LACP (requires switch configuration for port channel)
New-NetLbfoTeam `
-Name "StorageTeam" `
-TeamMembers "Ethernet 3", "Ethernet 4" `
-TeamingMode LACP `
-LoadBalancingAlgorithm IPAddresses `
-LacpTimer Fast `
-Confirm:$false
# View team status
Get-NetLbfoTeam
Get-NetLbfoTeamMember -Team "ProductionTeam"
Get-NetLbfoTeamNic -Team "ProductionTeam"
# Test NIC team failover
# Disconnect one cable physically and verify:
Get-NetLbfoTeamMember -Team "ProductionTeam" | Select-Object Name, AdministrativeMode, OperationalStatus
Configuring SET (Switch Embedded Teaming) for Hyper-V
For Hyper-V hosts, Switch Embedded Teaming (SET) is the preferred teaming method. SET is integrated into the Hyper-V Virtual Switch and supports RDMA (Remote Direct Memory Access), which is required for Storage Spaces Direct:
# Create a Hyper-V switch with SET (using two physical NICs)
New-VMSwitch `
-Name "SET-Switch" `
-NetAdapterName @("NIC1","NIC2") `
-EnableEmbeddedTeaming $true `
-AllowManagementOS $true `
-MinimumBandwidthMode Weight
# Configure Quality of Service for different traffic types
Set-VMSwitch -Name "SET-Switch" -MinimumBandwidthMode Weight
# Add virtual NICs for different traffic types
Add-VMNetworkAdapter -ManagementOS -SwitchName "SET-Switch" -Name "Management"
Add-VMNetworkAdapter -ManagementOS -SwitchName "SET-Switch" -Name "LiveMigration"
Add-VMNetworkAdapter -ManagementOS -SwitchName "SET-Switch" -Name "Storage"
# Assign bandwidth weights
Set-VMNetworkAdapter -ManagementOS -Name "Management" -MinimumBandwidthWeight 10
Set-VMNetworkAdapter -ManagementOS -Name "LiveMigration" -MinimumBandwidthWeight 30
Set-VMNetworkAdapter -ManagementOS -Name "Storage" -MinimumBandwidthWeight 50
Configuring Redundant Power and UPS Integration
Physical HA requires redundant power supplies connected to separate power circuits and UPS units. Configure Windows Server to communicate with the UPS:
# Windows Server uses the UPS vendor's software/agent for monitoring
# For APC UPS, install PowerChute or use the generic Windows UPS service:
# View the Windows UPS service
Get-Service ups
# Configure the UPS service (if using a serial UPS)
# Control Panel > Power Options > UPS
# For SNMP-capable UPS, use vendor SNMP MIB monitoring or PowerShell SNMP module
# Example: check UPS battery status via SNMP
# Requires SNMP Tools or vendor-specific monitoring
Database Mirroring and AlwaysOn for SQL Server HA
For database high availability on Windows Server 2019 with SQL Server, Always On Availability Groups provide near-synchronous or asynchronous database replication with automatic failover:
# The AlwaysOn setup requires Failover Clustering as a prerequisite
# Install SQL Server on all AG nodes first, then:
# Enable AlwaysOn on the primary SQL instance
Enable-SqlAlwaysOn -ServerInstance "SQL01" -Force
Enable-SqlAlwaysOn -ServerInstance "SQL02" -Force
# Create the availability group (after configuring endpoints)
New-SqlAvailabilityGroup `
-Name "AG-Production" `
-PrimaryServer "SQL01" `
-AvailabilityMode SynchronousCommit `
-FailoverMode Automatic `
-Database @("SalesDB","HRDatabase") `
-SecondarySqlServerInstances "SQL02"
Configuring DNS for High Availability
DNS must also be highly available. Use Active Directory-integrated DNS zones replicated to all domain controllers for automatic DNS HA. For standalone DNS, configure secondary zones:
# Ensure DNS is on multiple DCs (if using AD-integrated zones, this is automatic)
Get-DnsServerZone | Where-Object {$_.ZoneType -eq "Primary" -and $_.IsDsIntegrated -eq $true}
# Check replication scope (Forest replication provides the most redundancy)
Set-DnsServerPrimaryZone -Name "corp.example.com" -ReplicationScope Forest
# Test DNS resolution from multiple clients
Resolve-DnsName "www.corp.example.com" -Server 192.168.1.10
Resolve-DnsName "www.corp.example.com" -Server 192.168.1.11
Health Monitoring and Alerting
Proactive monitoring is essential for HA. Detect issues before they cause outages:
# Monitor critical Windows services with automatic restart on failure
# Configure service recovery options (restart service on first/second failure, reboot on third)
sc.exe failure "NTDS" reset= 86400 actions= restart/5000/restart/10000/restart/20000
sc.exe failure "DNS" reset= 86400 actions= restart/5000/restart/10000/restart/20000
sc.exe failure "W32Time" reset= 86400 actions= restart/5000/restart/10000/restart/20000
# Or using PowerShell module SCManager:
$service = Get-WmiObject Win32_Service -Filter "Name='NTDS'"
# Set up email alerts for critical events
# Use Windows Event Log to Task Scheduler integration:
$trigger = New-ScheduledTaskTrigger -AtStartup
$action = New-ScheduledTaskAction `
-Execute "powershell.exe" `
-Argument "-NonInteractive -Command Send-MailMessage -To '[email protected]' -From '[email protected]' -Subject 'Critical Event on $env:COMPUTERNAME' -SmtpServer smtp.corp.example.com"
# Monitor disk space
Get-PSDrive -PSProvider FileSystem | Where-Object {
($_.Free / ($_.Used + $_.Free)) -lt 0.15
} | ForEach-Object {
Write-Warning "Drive $($_.Name) is below 15% free space: $([math]::Round($_.Free/1GB,1)) GB remaining"
}
Configuring Windows Server HA for IIS
IIS web server HA requires multiple web servers with shared session state and a load balancer in front. Use Application Request Routing (ARR) or an external load balancer:
# Configure IIS Application Pool for automatic restart
Set-WebConfigurationProperty `
-Filter "system.applicationHost/applicationPools/add[@name='DefaultAppPool']/processModel" `
-Name "restartOnConfigChange" -Value $true
Set-WebConfigurationProperty `
-Filter "system.applicationHost/applicationPools/add[@name='DefaultAppPool']/recycling" `
-Name "logEventOnRecycle" -Value "Time,Memory,PrivateMemory,Requests"
# For session state: configure ASP.NET to use a shared SQL Server session store
# In web.config:
#
# Synchronize web content between nodes using DFS-R
New-DfsReplicationGroup -GroupName "WebContent-RG"
Add-DfsrMember -GroupName "WebContent-RG" -ComputerName "web01","web02"
Testing High Availability
Regularly test HA failover scenarios to ensure they work as expected. Untested HA is not really HA:
# Test NIC team failover (disconnect one NIC and check connectivity)
# Monitor team member state during the test
Watch-Command -Command { Get-NetLbfoTeamMember } -Interval 1
# Test DNS failover (disable DNS on one DC and verify resolution still works)
Stop-Service DNS -ComputerName "DC01"
Resolve-DnsName "corp.example.com"
Start-Service DNS -ComputerName "DC01"
# Test server failover with Failover Clustering
# (Covered in the Failover Clustering article)
Move-ClusterGroup -Name "File Server" -Node "node02"
# Verify recovery time
$start = Get-Date
# Perform failover test
$end = Get-Date
$rto = ($end - $start).TotalSeconds
"Recovery Time: $rto seconds"
High availability is an ongoing discipline, not a one-time configuration. Document your HA architecture, test failover scenarios quarterly, review single points of failure whenever infrastructure changes are made, and maintain runbooks for common failure scenarios so your team can respond quickly under pressure. The goal is to make recovery so practiced and automated that downtime becomes genuinely exceptional.