How to Configure Windows Server 2016 Tenant Virtual Networks
Tenant virtual networks in Windows Server 2016 are software-defined network constructs managed by the SDN Network Controller. They provide isolated, routable network environments for individual tenants or business units, enabling multiple parties to share the same physical infrastructure without interference. Each tenant virtual network has its own address space, subnets, routing policies, and access controls, and is completely isolated from all other tenant networks unless explicitly connected via peering or a gateway.
This tutorial provides a comprehensive walkthrough for creating and configuring tenant virtual networks using the Windows Server 2016 Network Controller, covering network creation, subnet configuration, VM attachment, DNS configuration, and access control policies.
Architecture of Tenant Virtual Networks
A tenant virtual network in Windows Server 2016 SDN consists of the network object itself, which defines the address space and encapsulation type, one or more subnet objects within that address space, network interface objects that connect VMs to the subnets, and optional access control lists that govern which traffic is allowed. The Network Controller distributes all of this configuration to the Hyper-V Virtual Switch on each host via the host agent, enforcing the policies at the hypervisor level.
Prerequisites
You need a deployed Windows Server 2016 SDN environment including the Network Controller, the HNV Provider logical network, and Hyper-V hosts with the SDN host agent installed. Verify that the Network Controller REST API is accessible:
$uri = "https://nc.contoso.com"
Invoke-RestMethod -Uri "$uri/networking/v1/discover" -UseDefaultCredentials
Step 1 — Create the Tenant Virtual Network
Define the tenant virtual network with its address space and encapsulation type. Windows Server 2016 supports VXLAN and NVGRE encapsulation:
$headers = @{ "Content-Type" = "application/json" }
$vnetBody = @{
properties = @{
addressSpace = @{
addressPrefixes = @("10.100.0.0/16")
}
encapType = "VXLAN"
dhcpOptions = @{
dnsServers = @("10.100.0.10")
}
logicalNetwork = @{
resourceRef = "/logicalNetworks/HNVProvider"
}
}
} | ConvertTo-Json -Depth 6
Invoke-RestMethod `
-Uri "$uri/networking/v1/virtualNetworks/TenantAVNet" `
-Method Put `
-Body $vnetBody `
-Headers $headers `
-UseDefaultCredentials
Step 2 — Add Subnets to the Virtual Network
Add one or more subnets within the virtual network’s address space. Each subnet can have its own ACL applied:
$subnetBody = @{
properties = @{
addressPrefix = "10.100.1.0/24"
ipPools = @(@{
properties = @{
startIpAddress = "10.100.1.1"
endIpAddress = "10.100.1.254"
}
})
}
} | ConvertTo-Json -Depth 5
Invoke-RestMethod `
-Uri "$uri/networking/v1/virtualNetworks/TenantAVNet/subnets/TenantA-Subnet1" `
-Method Put `
-Body $subnetBody `
-Headers $headers `
-UseDefaultCredentials
Step 3 — Create a Network Interface for a Tenant VM
Create a network interface object that will be assigned to a tenant VM. This binds the VM to the virtual subnet and assigns it an IP address:
$nicBody = @{
properties = @{
macAddress = "00-22-33-44-55-66"
ipConfigurations = @(@{
properties = @{
privateIPAddress = "10.100.1.11"
privateIPAllocationMethod = "Static"
subnet = @{
resourceRef = "/virtualNetworks/TenantAVNet/subnets/TenantA-Subnet1"
}
}
})
dnsSettings = @{
dnsServers = @("10.100.0.10")
}
}
} | ConvertTo-Json -Depth 6
Invoke-RestMethod `
-Uri "$uri/networking/v1/networkInterfaces/TenantA-VM1-NIC" `
-Method Put `
-Body $nicBody `
-Headers $headers `
-UseDefaultCredentials
Step 4 — Retrieve the Instance ID and Apply to the VM
After creating the network interface, retrieve its InstanceId (a GUID) from the Network Controller. This GUID must be set as the port profile ID on the corresponding Hyper-V VM network adapter to link the VM to the SDN policy:
$nic = Invoke-RestMethod `
-Uri "$uri/networking/v1/networkInterfaces/TenantA-VM1-NIC" `
-Method Get `
-UseDefaultCredentials
$instanceId = $nic.instanceId
Write-Host "Instance ID: $instanceId"
On the Hyper-V host, apply the instance ID to the VM adapter:
$vmName = "TenantA-VM1"
$adapterName = "Network Adapter"
Set-VMNetworkAdapterPortProfile `
-VMName $vmName `
-VMNetworkAdapterName $adapterName `
-ProfileId $instanceId `
-ProfileData 1
Step 5 — Configure Access Control Lists
Apply an ACL to the subnet to control which traffic is permitted. First define the ACL:
$aclBody = @{
properties = @{
aclRules = @(
@{
properties = @{
protocol = "TCP"
sourcePortRange = "0-65535"
destinationPortRange = "443"
action = "Allow"
sourceAddressPrefix = "*"
destinationAddressPrefix = "10.100.1.0/24"
priority = 100
type = "Inbound"
logging = "Enabled"
}
},
@{
properties = @{
protocol = "All"
sourcePortRange = "0-65535"
destinationPortRange = "0-65535"
action = "Deny"
sourceAddressPrefix = "*"
destinationAddressPrefix = "*"
priority = 200
type = "Inbound"
logging = "Enabled"
}
}
)
}
} | ConvertTo-Json -Depth 7
Invoke-RestMethod `
-Uri "$uri/networking/v1/accessControlLists/TenantA-ACL" `
-Method Put `
-Body $aclBody `
-Headers $headers `
-UseDefaultCredentials
Step 6 — Verify the Virtual Network Configuration
Confirm all objects are correctly configured:
Invoke-RestMethod `
-Uri "$uri/networking/v1/virtualNetworks/TenantAVNet" `
-Method Get `
-UseDefaultCredentials | ConvertTo-Json -Depth 5
Conclusion
Configuring tenant virtual networks on Windows Server 2016 SDN gives each tenant a fully isolated, independently managed network environment built entirely in software. The Network Controller handles the distribution of all policies and mappings, while Hyper-V Network Virtualisation provides the encapsulation and enforcement. This approach allows datacenter operators to rapidly provision, modify, and decommission tenant networks without any changes to the physical infrastructure, enabling true network agility.