How to Configure Windows Server Software-Defined Networking (SDN) on Windows Server 2025
Software-Defined Networking (SDN) separates the network control plane from the data plane, enabling centralized, programmable management of network infrastructure through software rather than device-by-device configuration. Windows Server 2025 includes a mature, Microsoft-supported SDN stack built natively into Hyper-V and managed through the Network Controller role. This architecture powers environments ranging from large enterprise private clouds to Azure Stack HCI deployments. In this tutorial, you will learn the SDN component architecture, install and configure the Network Controller, define logical networks and virtual network objects, implement microsegmentation with SDN ACLs, configure Software Load Balancing for inbound NAT, and understand how Hyper-V Network Virtualization (HNV) underpins the entire stack. While a full production SDN deployment typically involves System Center Virtual Machine Manager (VMM) or Windows Admin Center for orchestration, this guide focuses on the PowerShell-based approach so you understand what is happening beneath the GUI.
Prerequisites
- At least three Windows Server 2025 Datacenter hosts with Hyper-V enabled (two compute hosts + one management/NC host is the minimum)
- All Hyper-V hosts joined to the same Active Directory domain
- Dedicated VLANs for: Management network, Provider (PA) network, and optionally Transit and HNV Provider networks
- RDMA-capable NICs or NIC teaming (SET — Switch Embedded Teaming) configured on compute hosts
- A Hyper-V switch created on each compute host with SET enabled
- Static IP addresses on all management interfaces
- DNS SRV records or manual host entries for all SDN nodes
- PowerShell 5.1 or later with RSAT-NetworkController module, running as Domain Admin
Step 1 — Install the Network Controller Role
The Network Controller (NC) is the brain of the Windows SDN stack. It stores network policy, communicates with Hyper-V hosts via a southbound API, and exposes a northbound REST API for management tools. For production, deploy NC as a cluster of three VMs for high availability. For this tutorial, a single NC deployment is shown.
# On the Network Controller VM — install the role and management tools
Install-WindowsFeature NetworkController -IncludeManagementTools
Install-WindowsFeature RSAT-NetworkController
# Verify the role is installed
Get-WindowsFeature NetworkController | Select-Object Name, InstallState
After installing the role, configure the Network Controller cluster. This step deploys the NC cluster nodes, establishes the REST endpoint, and sets the management security group:
# Step 1: Create NC node objects
$NodeObject = New-NetworkControllerNodeObject `
-Name "NC01" `
-Server "NC01.corp.example.com" `
-FaultDomain "fd:/rack1/NC01" `
-RestInterface "Ethernet"
# Step 2: Install the NC cluster (single-node for lab)
Install-NetworkControllerCluster `
-Node $NodeObject `
-ClusterAuthentication Kerberos `
-ManagementSecurityGroup "CORPSDN-Admins" `
-CredentialEncryptionCertificate (Get-Item Cert:LocalMachineMy)
# Step 3: Install the NC application on the cluster
Install-NetworkController `
-Node $NodeObject `
-ClientAuthentication Kerberos `
-ClientSecurityGroup "CORPSDN-Admins" `
-RestIpAddress "192.168.100.10/24" `
-ServerCertificate (Get-Item Cert:LocalMachineMy)
# Verify the NC REST endpoint is responding
Get-NetworkController
Replace <thumbprint> with the actual thumbprint of the SSL certificate issued for the NC REST endpoint. In production, this certificate should be issued by your enterprise CA and trusted by all hosts.
Step 2 — Configure Hyper-V Hosts as SDN Compute Nodes
Each Hyper-V compute host must be registered with the Network Controller and must have the Host Agent service running. The SDN Host Agent bridges the NC’s intent (stored as REST objects) to the actual Hyper-V vSwitch policy on each host.
# On each compute host — install the SDN Host Agent
Install-WindowsFeature NetworkVirtualization, DataCenterBridging
# Deploy the SDN Host Agent (this step is typically done via a deployment script
# such as SDNExpress.ps1 from the SDN repository, but the key cmdlet is shown here)
# The NC REST URI is the endpoint configured above
$uri = "https://nc01.corp.example.com"
# Register the compute host with the Network Controller
# (In practice, SDNExpress handles this; the underlying REST call creates a Servers resource)
$credential = Get-Credential
$hostCred = New-Object Microsoft.Windows.NetworkController.CredentialProperties
$hostCred.Type = "X509Certificate"
$hostCred.Value = ""
New-NetworkControllerCredential `
-ConnectionUri $uri `
-ResourceId "ComputeHost01-Cred" `
-Properties $hostCred
# Verify host registration via REST
Get-NetworkControllerServer -ConnectionUri $uri |
Select-Object ResourceId, Properties
Step 3 — Create Logical Networks and Subnets
Logical networks represent the physical network topology as seen by the SDN stack. You define a logical network for each physical VLAN, then create subnets within each logical network. These become the Provider Address (PA) subnets used by HNV for encapsulation.
$uri = "https://nc01.corp.example.com"
# Define the HNV Provider logical network
$hnvProviderNetwork = New-Object Microsoft.Windows.NetworkController.LogicalNetworkProperties
$hnvProviderNetwork.NetworkVirtualizationEnabled = $true
$hnvLN = New-NetworkControllerLogicalNetwork `
-ConnectionUri $uri `
-ResourceId "HNVProviderLogicalNetwork" `
-Properties $hnvProviderNetwork
# Add a subnet to the logical network (the PA subnet)
$paSubnetProps = New-Object Microsoft.Windows.NetworkController.LogicalSubnetProperties
$paSubnetProps.AddressPrefix = "10.10.0.0/24"
$paSubnetProps.DefaultGateways = @("10.10.0.1")
$paSubnetProps.VlanID = 100
New-NetworkControllerLogicalSubnet `
-ConnectionUri $uri `
-LogicalNetworkId "HNVProviderLogicalNetwork" `
-ResourceId "PASubnet-1" `
-Properties $paSubnetProps
# Verify the logical network was created
Get-NetworkControllerLogicalNetwork -ConnectionUri $uri |
Select-Object ResourceId
Step 4 — Create Virtual Networks (Tenant Networks)
Virtual networks are the tenant-facing constructs in SDN. Each virtual network is isolated from others through HNV encapsulation (VXLAN or NVGRE). Multiple tenants can use the same overlapping IP address ranges because their traffic is encapsulated in separate tunnels identified by Virtual Subnet IDs (VSIDs).
$uri = "https://nc01.corp.example.com"
# Create a virtual network for Tenant A
$tenantNetworkProps = New-Object Microsoft.Windows.NetworkController.VirtualNetworkProperties
$tenantNetworkProps.AddressSpace = New-Object Microsoft.Windows.NetworkController.AddressSpace
$tenantNetworkProps.AddressSpace.AddressPrefixes = @("172.16.0.0/16")
$tenantNetworkProps.LogicalNetwork = (Get-NetworkControllerLogicalNetwork `
-ConnectionUri $uri -ResourceId "HNVProviderLogicalNetwork")
$tenantVN = New-NetworkControllerVirtualNetwork `
-ConnectionUri $uri `
-ResourceId "TenantA-VirtualNetwork" `
-Properties $tenantNetworkProps
# Add a subnet to the virtual network
$vSubnetProps = New-Object Microsoft.Windows.NetworkController.VirtualSubnetProperties
$vSubnetProps.AddressPrefix = "172.16.10.0/24"
New-NetworkControllerVirtualSubnet `
-ConnectionUri $uri `
-VirtualNetworkId "TenantA-VirtualNetwork" `
-ResourceId "TenantA-Subnet1" `
-Properties $vSubnetProps
HNV encapsulates the tenant virtual network traffic inside VXLAN or NVGRE headers, allowing VMs on different physical hosts to communicate as if they were on the same Layer 2 segment, regardless of the underlying physical network topology. The choice between VXLAN and NVGRE is configured at the logical network level via the Encapsulation property.
Step 5 — Implement Microsegmentation with SDN ACLs
SDN Access Control Lists (ACLs) implement distributed firewall policy at the virtual NIC level. Unlike traditional perimeter firewalls, SDN ACLs are enforced by the Hyper-V vSwitch on each host, meaning east-west traffic between VMs on the same host is also inspected and controlled.
$uri = "https://nc01.corp.example.com"
# Create an ACL that allows web traffic inbound and blocks all other inbound
$aclProps = New-Object Microsoft.Windows.NetworkController.AccessControlListProperties
$rules = @()
# Rule 1: Allow inbound HTTP
$r1 = New-Object Microsoft.Windows.NetworkController.AclRule
$r1.Protocol = "TCP"
$r1.SourcePortRange = "*"
$r1.DestinationPortRange = "80"
$r1.Action = "Allow"
$r1.SourceAddressPrefix = "*"
$r1.DestinationAddressPrefix = "*"
$r1.Priority = 100
$r1.Type = "Inbound"
$rules += $r1
# Rule 2: Allow inbound HTTPS
$r2 = New-Object Microsoft.Windows.NetworkController.AclRule
$r2.Protocol = "TCP"
$r2.SourcePortRange = "*"
$r2.DestinationPortRange = "443"
$r2.Action = "Allow"
$r2.SourceAddressPrefix = "*"
$r2.DestinationAddressPrefix = "*"
$r2.Priority = 110
$r2.Type = "Inbound"
$rules += $r2
# Rule 3: Deny all other inbound
$r3 = New-Object Microsoft.Windows.NetworkController.AclRule
$r3.Protocol = "All"
$r3.SourcePortRange = "*"
$r3.DestinationPortRange = "*"
$r3.Action = "Deny"
$r3.SourceAddressPrefix = "*"
$r3.DestinationAddressPrefix = "*"
$r3.Priority = 65000
$r3.Type = "Inbound"
$rules += $r3
$aclProps.AclRules = $rules
New-NetworkControllerAccessControlList `
-ConnectionUri $uri `
-ResourceId "WebTier-ACL" `
-Properties $aclProps
Step 6 — Configure Software Load Balancer for Inbound NAT
The SDN Software Load Balancer (SLB) provides both inbound NAT (mapping a public VIP to private backend VMs) and outbound NAT (allowing VMs without public IPs to reach the internet). The SLB MUX (multiplexer) component runs as a VM on your cluster and uses BGP to advertise VIP addresses to upstream routers.
$uri = "https://nc01.corp.example.com"
# Create a public IP address object (the VIP)
$publicIPProps = New-Object Microsoft.Windows.NetworkController.PublicIPAddressProperties
$publicIPProps.IPAddress = "203.0.113.50"
$publicIPProps.PublicIPAllocationMethod = "Static"
$publicIPProps.IdleTimeoutInMinutes = 4
$vip = New-NetworkControllerPublicIPAddress `
-ConnectionUri $uri `
-ResourceId "WebFrontend-VIP" `
-Properties $publicIPProps
# Create an inbound NAT rule mapping VIP:443 to backend VM:443
$natProps = New-Object Microsoft.Windows.NetworkController.InboundNatRuleProperties
$natProps.Protocol = "TCP"
$natProps.FrontendPort = 443
$natProps.BackendPort = 443
$natProps.EnableFloatingIP = $false
$natProps.FrontendIPConfigurations = @($vip)
New-NetworkControllerInboundNatRule `
-ConnectionUri $uri `
-LoadBalancerId "WebFrontend-LB" `
-ResourceId "HTTPS-InboundNAT" `
-Properties $natProps
Conclusion
Windows Server 2025 SDN brings enterprise-grade network programmability to organizations that want to avoid proprietary hardware lock-in. By deploying the Network Controller, defining logical and virtual networks using HNV encapsulation, applying distributed microsegmentation through SDN ACLs, and using the Software Load Balancer for VIP management, you gain the flexibility to move workloads, enforce security policy, and scale network capacity entirely through software. The PowerShell REST-based approach shown in this tutorial forms the same foundation used by Windows Admin Center, System Center VMM, and Azure Stack HCI — understanding it gives you full insight into and control over your SDN infrastructure regardless of which orchestration layer sits above it.