How to Configure Windows Server 2019 Software Load Balancer
Software Load Balancer (SLB) is a component of the Windows Server 2019 Software Defined Networking (SDN) stack that provides inbound and outbound network traffic load balancing and Network Address Translation (NAT). SLB operates at Layer 4 (TCP/UDP) and distributes connections across backend server pools using ECMP (Equal Cost Multi-Path) routing and VXLAN encapsulation. It integrates with Network Controller to provide a programmable, scalable alternative to hardware load balancers. This guide covers deploying SLB MUX and DIP agents and configuring load balancing rules.
Software Load Balancer Architecture
The SLB infrastructure consists of three components. The SLB Multiplexer (MUX) is a VM role that receives inbound traffic on Virtual IPs (VIPs) and forwards it to backend Dynamic IPs (DIPs) using ECMP and BGP. The SLB Host Agent runs on each Hyper-V host and programs the host’s Hyper-V vSwitch with SLB policy information. The SLB Manager in Network Controller coordinates configuration across MUX VMs and Host Agents. Multiple MUX VMs provide scale-out and high availability.
Prerequisites
# SLB requires Network Controller to be deployed and operational
# Verify Network Controller is running
Get-NetworkControllerCluster | Select-Object ClusterState
# Install required features on SLB MUX VMs (Windows Server 2019 Datacenter)
Install-WindowsFeature -Name NetworkController
Install-WindowsFeature -Name RSAT-NetworkController
# Each Hyper-V host needs the SLB Host Agent
# This is typically deployed via the SLB Host Agent MSI
# Included in the SDN Express deployment scripts
# Verify BGP is available (SLB MUX uses BGP to advertise VIPs)
Install-WindowsFeature -Name RSAT-RemoteAccess-Mgmt
Deploying SLB MUX VMs
$ncUri = "https://networkcontroller.domain.local"
$credential = Get-Credential -Message "Enter Network Controller credentials"
# Create a load balancer manager configuration resource
$lbmProperties = New-Object Microsoft.Windows.NetworkController.LoadBalancerManagerProperties
$lbmProperties.LoadBalancingAlgorithm = "EqualCostMultiPath"
Set-NetworkControllerLoadBalancerConfiguration `
-ConnectionUri $ncUri `
-Properties $lbmProperties `
-Credential $credential
# Register an SLB MUX VM with Network Controller
$muxProperties = New-Object Microsoft.Windows.NetworkController.LoadBalancerMuxProperties
$muxProperties.RouterConfiguration = New-Object Microsoft.Windows.NetworkController.RouterConfiguration
# BGP peer configuration (connect MUX to physical router/ToR switch)
$bgpPeer = New-Object Microsoft.Windows.NetworkController.RouterConfiguration
$bgpPeer.LocalASN = 64512
$bgpPeer.PeerASN = 64513
$bgpPeer.RouterIPAddress = "192.168.100.1"
$muxProperties.RouterConfiguration = $bgpPeer
New-NetworkControllerLoadBalancerMux `
-ConnectionUri $ncUri `
-ResourceId "SLB-MUX-01" `
-Properties $muxProperties `
-Credential $credential `
-PassInnerException
Creating a Virtual IP (VIP) and Load Balancing Rule
$ncUri = "https://networkcontroller.domain.local"
$credential = Get-Credential
# Create a public VIP IP pool
$publicIPProperties = New-Object Microsoft.Windows.NetworkController.PublicIPAddressProperties
$publicIPProperties.IPAddress = "203.0.113.100"
$publicIPProperties.PublicIPAllocationMethod = "Static"
$vip = New-NetworkControllerPublicIpAddress `
-ResourceId "WebVIP-01" `
-Properties $publicIPProperties `
-ConnectionUri $ncUri `
-Credential $credential `
-PassInnerException
# Create backend address pool with web servers
$backendPoolProperties = New-Object Microsoft.Windows.NetworkController.LoadBalancerBackendAddressPoolProperties
New-NetworkControllerLoadBalancerBackendAddressPool `
-ResourceId "WebPool-01" `
-Properties $backendPoolProperties `
-ConnectionUri $ncUri `
-Credential $credential
# Add backend NICs (web servers) to the pool
# Each web server VM's NIC must be registered with Network Controller
$nics = @("webvm01-nic","webvm02-nic","webvm03-nic")
foreach ($nic in $nics) {
$nicResource = Get-NetworkControllerNetworkInterface -ResourceId $nic -ConnectionUri $ncUri -Credential $credential
$nicResource.Properties.IpConfigurations[0].Properties.LoadBalancerBackendAddressPools += @{
ResourceRef = "/loadBalancers/WebLB-01/backendAddressPools/WebPool-01"
}
Set-NetworkControllerNetworkInterface -ResourceId $nic -Properties $nicResource.Properties `
-ConnectionUri $ncUri -Credential $credential
}
Configuring Load Balancing Rules
$ncUri = "https://networkcontroller.domain.local"
$credential = Get-Credential
# Create health probe for HTTP (GET /health)
$probeProperties = New-Object Microsoft.Windows.NetworkController.LoadBalancerProbeProperties
$probeProperties.Protocol = "HTTP"
$probeProperties.Port = 80
$probeProperties.RequestPath = "/health"
$probeProperties.IntervalInSeconds = 15
$probeProperties.NumberOfProbes = 2
New-NetworkControllerLoadBalancerProbe `
-LoadBalancerId "WebLB-01" `
-ResourceId "HTTP-Probe" `
-Properties $probeProperties `
-ConnectionUri $ncUri `
-Credential $credential
# Create the load balancing rule: VIP:80 -> Pool:80
$lbRuleProperties = New-Object Microsoft.Windows.NetworkController.LoadBalancingRuleProperties
$lbRuleProperties.Protocol = "TCP"
$lbRuleProperties.FrontendPort = 80
$lbRuleProperties.BackendPort = 80
$lbRuleProperties.IdleTimeoutInMinutes = 4
$lbRuleProperties.EnableFloatingIP = $false
$lbRuleProperties.LoadDistribution = "SourceIPProtocol"
# Link to frontend IP (VIP), backend pool, and health probe
$lbRuleProperties.FrontendIPConfigurations = @{
ResourceRef = "/loadBalancers/WebLB-01/frontendIPConfigurations/WebVIP-Frontend"
}
$lbRuleProperties.BackendAddressPool = @{
ResourceRef = "/loadBalancers/WebLB-01/backendAddressPools/WebPool-01"
}
$lbRuleProperties.Probe = @{
ResourceRef = "/loadBalancers/WebLB-01/probes/HTTP-Probe"
}
New-NetworkControllerLoadBalancerLoadBalancingRule `
-LoadBalancerId "WebLB-01" `
-ResourceId "HTTP-LB-Rule" `
-Properties $lbRuleProperties `
-ConnectionUri $ncUri `
-Credential $credential
Configuring Outbound NAT
# Configure outbound NAT so backend VMs can reach the internet
$outboundRuleProperties = New-Object Microsoft.Windows.NetworkController.LoadBalancerOutboundNatRuleProperties
$outboundRuleProperties.Protocol = "All"
$outboundRuleProperties.FrontendIPConfigurations = @{
ResourceRef = "/loadBalancers/WebLB-01/frontendIPConfigurations/WebVIP-Frontend"
}
$outboundRuleProperties.BackendAddressPool = @{
ResourceRef = "/loadBalancers/WebLB-01/backendAddressPools/WebPool-01"
}
New-NetworkControllerLoadBalancerOutboundNatRule `
-LoadBalancerId "WebLB-01" `
-ResourceId "Outbound-NAT" `
-Properties $outboundRuleProperties `
-ConnectionUri $ncUri `
-Credential $credential
Monitoring SLB Health
# Check SLB MUX status
Get-NetworkControllerLoadBalancerMux -ConnectionUri $ncUri -Credential $credential |
Select-Object ResourceId, Properties
# Check load balancer backend pool members and their health
Get-NetworkControllerLoadBalancerBackendAddressPool `
-LoadBalancerId "WebLB-01" `
-ConnectionUri $ncUri `
-Credential $credential |
Select-Object ResourceId, Properties
# View SLB statistics from the MUX VM
# Run on the SLB MUX VM:
Get-Counter -Counter "SLB MUX(*)*" -SampleInterval 5 -MaxSamples 6 |
Select-Object -ExpandProperty CounterSamples |
Where-Object { $_.CookedValue -gt 0 } |
Select-Object Path, CookedValue | Format-Table -AutoSize
Software Load Balancer on Windows Server 2019 provides a cost-effective alternative to hardware load balancers in SDN environments, particularly for organizations already running Windows Server-based SDN infrastructure with Network Controller. The REST API-based management model enables infrastructure-as-code practices where load balancer configurations are defined in version-controlled templates and deployed through CI/CD pipelines. Monitor MUX CPU and throughput performance and scale out by adding additional MUX VMs as workload increases.