Task 02: Enable SDN Integration
DOCUMENT CATEGORY: Runbook SCOPE: SDN enablement PURPOSE: Enable SDN via Azure Arc integration MASTER REFERENCE: Microsoft Learn - Enable SDN Integration
Status: Active
Overview
This step enables SDN integration on Azure Local using the Add-EceFeature PowerShell cmdlet. Once enabled, the Network Controller runs as a Failover Cluster service and integrates with the Azure Arc control plane.
- Verify all prerequisites from Step 1 are met
- This process cannot be reversed without cluster redeployment
- Do not use on-premises SDN tools (WAC, SDN Express) after enabling
What Happens When SDN is Enabled
- Network Controller is deployed as a Failover Cluster service (not VMs)
- Azure Virtual Filtering extensions are enabled on the virtual switch
- Arc integration allows management via Azure Portal, CLI, and ARM templates
- Existing logical networks become manageable through Azure
Execution Options
- Direct Script (On Node)
- Orchestrated Script (Mgmt Server)
- Standalone Script
Run this script directly on any Azure Local cluster node.
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Enables SDN integration on the local Azure Local cluster.
.DESCRIPTION
This script enables SDN via Azure Arc by running Add-EceFeature.
The Network Controller will be deployed as a Failover Cluster service.
.PARAMETER Confirm
Skip confirmation prompt.
#>
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory = $false)]
[switch]$Force
)
$ErrorActionPreference = 'Stop'
Write-Host "=" * 60 -ForegroundColor Cyan
Write-Host "Enable SDN Integration on Azure Local" -ForegroundColor Cyan
Write-Host "=" * 60 -ForegroundColor Cyan
# Pre-flight checks
Write-Host "`n[Pre-Flight] Verifying cluster status..." -ForegroundColor Yellow
$registration = Get-AzStackHCI
if ($registration.ConnectionStatus -ne 'Connected') {
throw "Cluster is not connected to Azure Arc. Status: $($registration.ConnectionStatus)"
}
Write-Host " ✓ Cluster connected to Azure Arc" -ForegroundColor Green
# Check if SDN is already enabled
Write-Host "`n[Pre-Flight] Checking current SDN status..." -ForegroundColor Yellow
try {
$sdnFeature = Get-EceFeature -Name "SDN" -ErrorAction SilentlyContinue
if ($sdnFeature -and $sdnFeature.State -eq "Enabled") {
Write-Host " ⚠ SDN is already enabled on this cluster" -ForegroundColor Yellow
return
}
} catch {
Write-Host " SDN feature not currently enabled" -ForegroundColor Gray
}
# Confirmation
if (-not $Force) {
Write-Host "`n" + "=" * 60 -ForegroundColor Yellow
Write-Host "WARNING: You are about to enable SDN on this cluster" -ForegroundColor Yellow
Write-Host "=" * 60 -ForegroundColor Yellow
Write-Host @"
This action will:
- Deploy Network Controller as a Failover Cluster service
- Enable Azure Virtual Filtering extensions on the virtual switch
- Integrate with Azure Arc for management
This action:
- Cannot be easily reversed
- Requires cluster to remain connected to Azure
- Is incompatible with on-premises SDN tools (WAC, SDN Express)
"@ -ForegroundColor Yellow
$response = Read-Host "Do you want to proceed? (yes/no)"
if ($response -ne 'yes') {
Write-Host "Operation cancelled by user" -ForegroundColor Red
return
}
}
# Enable SDN
Write-Host "`n[Enabling SDN] Running Add-EceFeature..." -ForegroundColor Yellow
Write-Host " This may take 10-15 minutes..." -ForegroundColor Gray
try {
# Enable SDN feature
Add-EceFeature -FeatureName "SDN" -Verbose
Write-Host "`n ✓ SDN feature enabled successfully" -ForegroundColor Green
} catch {
Write-Host "`n ✗ Failed to enable SDN: $_" -ForegroundColor Red
throw
}
# Wait for Network Controller to be ready
Write-Host "`n[Verification] Waiting for Network Controller to be ready..." -ForegroundColor Yellow
$timeout = 300 # 5 minutes
$elapsed = 0
$interval = 15
while ($elapsed -lt $timeout) {
try {
$ncClusterResource = Get-ClusterResource | Where-Object { $_.ResourceType -eq "Network Controller" }
if ($ncClusterResource -and $ncClusterResource.State -eq "Online") {
Write-Host " ✓ Network Controller is online" -ForegroundColor Green
break
}
} catch {
# Continue waiting
}
Write-Host " Waiting... ($elapsed seconds)" -ForegroundColor Gray
Start-Sleep -Seconds $interval
$elapsed += $interval
}
if ($elapsed -ge $timeout) {
Write-Host " ⚠ Timeout waiting for Network Controller. Check cluster resources manually." -ForegroundColor Yellow
}
# Verify Virtual Filtering extensions
Write-Host "`n[Verification] Checking Virtual Filtering extensions..." -ForegroundColor Yellow
$vmSwitch = Get-VMSwitch | Where-Object { $_.SwitchType -eq 'External' }
foreach ($switch in $vmSwitch) {
$vfpExtension = Get-VMSwitchExtension -VMSwitchName $switch.Name | Where-Object { $_.Name -match "Azure|VFP" }
if ($vfpExtension -and $vfpExtension.Enabled) {
Write-Host " ✓ VFP extension enabled on switch: $($switch.Name)" -ForegroundColor Green
} else {
Write-Host " ⚠ VFP extension not found/enabled on switch: $($switch.Name)" -ForegroundColor Yellow
}
}
# Final summary
Write-Host "`n" + "=" * 60 -ForegroundColor Cyan
Write-Host "SDN Enablement Complete" -ForegroundColor Cyan
Write-Host "=" * 60 -ForegroundColor Cyan
Write-Host @"
SDN is now enabled on this cluster. You can manage SDN resources via:
- Azure Portal: Networking > Logical Networks
- Azure CLI: az stack-hci-vm network
- ARM Templates
Next step: Configure Network Security Groups (Step 3)
"@ -ForegroundColor Green
Run this script from the management server to enable SDN remotely.
#Requires -Modules Az.Accounts, Az.StackHCI
<#
.SYNOPSIS
Enables SDN integration on an Azure Local cluster from a management server.
.DESCRIPTION
This script connects to a cluster node and runs the SDN enablement process remotely.
.PARAMETER NodeName
The name of a cluster node to connect to.
.PARAMETER Credential
Credentials for connecting to cluster nodes.
.PARAMETER Force
Skip confirmation prompts.
#>
[CmdletBinding(SupportsShouldProcess)]
param(
[Parameter(Mandatory = $true)]
[string]$NodeName,
[Parameter(Mandatory = $false)]
[PSCredential]$Credential,
[Parameter(Mandatory = $false)]
[switch]$Force
)
$ErrorActionPreference = 'Stop'
Write-Host "=" * 60 -ForegroundColor Cyan
Write-Host "Enable SDN Integration (Remote)" -ForegroundColor Cyan
Write-Host "Target Node: $NodeName" -ForegroundColor Cyan
Write-Host "=" * 60 -ForegroundColor Cyan
# Build remote session parameters
$sessionParams = @{
ComputerName = $NodeName
}
if ($Credential) {
$sessionParams.Credential = $Credential
}
# Create persistent session
Write-Host "`nCreating remote session to $NodeName..." -ForegroundColor Yellow
$session = New-PSSession @sessionParams
try {
# Pre-flight check
Write-Host "`n[Pre-Flight] Verifying cluster status..." -ForegroundColor Yellow
$preCheck = Invoke-Command -Session $session -ScriptBlock {
$reg = Get-AzStackHCI
@{
ClusterName = $reg.ClusterName
ConnectionStatus = $reg.ConnectionStatus
Version = $reg.ClusterVersion
}
}
Write-Host " Cluster: $($preCheck.ClusterName)" -ForegroundColor Gray
Write-Host " Version: $($preCheck.Version)" -ForegroundColor Gray
Write-Host " Arc Status: $($preCheck.ConnectionStatus)" -ForegroundColor Gray
if ($preCheck.ConnectionStatus -ne 'Connected') {
throw "Cluster is not connected to Azure Arc"
}
Write-Host " ✓ Pre-flight checks passed" -ForegroundColor Green
# Confirmation
if (-not $Force) {
Write-Host "`n" + "!" * 60 -ForegroundColor Yellow
Write-Host "WARNING: About to enable SDN on cluster $($preCheck.ClusterName)" -ForegroundColor Yellow
Write-Host "!" * 60 -ForegroundColor Yellow
$response = Read-Host "Type 'yes' to proceed"
if ($response -ne 'yes') {
Write-Host "Operation cancelled" -ForegroundColor Red
return
}
}
# Enable SDN
Write-Host "`n[Enabling SDN] This may take 10-15 minutes..." -ForegroundColor Yellow
Invoke-Command -Session $session -ScriptBlock {
Add-EceFeature -FeatureName "SDN" -Verbose
}
Write-Host " ✓ SDN enablement command completed" -ForegroundColor Green
# Verify
Write-Host "`n[Verification] Checking Network Controller status..." -ForegroundColor Yellow
$verification = Invoke-Command -Session $session -ScriptBlock {
Start-Sleep -Seconds 30 # Allow time for services to start
$nc = Get-ClusterResource | Where-Object { $_.ResourceType -eq "Network Controller" }
@{
NCOnline = ($nc -and $nc.State -eq "Online")
NCState = if ($nc) { $nc.State } else { "Not Found" }
}
}
if ($verification.NCOnline) {
Write-Host " ✓ Network Controller is online" -ForegroundColor Green
} else {
Write-Host " ⚠ Network Controller state: $($verification.NCState)" -ForegroundColor Yellow
Write-Host " Allow a few more minutes for initialization" -ForegroundColor Gray
}
# Summary
Write-Host "`n" + "=" * 60 -ForegroundColor Cyan
Write-Host "SDN Enablement Complete" -ForegroundColor Cyan
Write-Host "=" * 60 -ForegroundColor Cyan
Write-Host "`nNext step: Configure Network Security Groups (Step 3)" -ForegroundColor Green
} finally {
# Clean up session
Remove-PSSession -Session $session
}
Copy-paste ready SDN enablement script — no config file, no helpers, no dependencies.
# ============================================================================
# Script: Enable-SDNIntegration-Standalone.ps1
# Execution: Run ON an Azure Local cluster node — fully self-contained
# Prerequisites: PowerShell, Azure Local 2601+, Arc-connected cluster
# ============================================================================
#region CONFIGURATION
# ── No environment-specific values needed — SDN is enabled on the local cluster ──
$SkipConfirmation = $false # Set to $true to skip the confirmation prompt
#endregion CONFIGURATION
$ErrorActionPreference = 'Stop'
Write-Host "=" * 60 -ForegroundColor Cyan
Write-Host "Enable SDN Integration (Standalone)" -ForegroundColor Cyan
Write-Host "=" * 60 -ForegroundColor Cyan
# Pre-flight: verify Arc connection
$registration = Get-AzStackHCI
if ($registration.ConnectionStatus -ne 'Connected') {
throw "Cluster is not connected to Azure Arc. Status: $($registration.ConnectionStatus)"
}
Write-Host " ✓ Cluster connected to Azure Arc" -ForegroundColor Green
# Check if already enabled
try {
$sdnFeature = Get-EceFeature -Name "SDN" -ErrorAction SilentlyContinue
if ($sdnFeature -and $sdnFeature.State -eq "Enabled") {
Write-Host " ⚠ SDN is already enabled on this cluster" -ForegroundColor Yellow
return
}
} catch { Write-Host " SDN not currently enabled" -ForegroundColor Gray }
# Confirmation
if (-not $SkipConfirmation) {
Write-Host "`nWARNING: This will deploy Network Controller and enable Azure Virtual Filtering." -ForegroundColor Yellow
Write-Host "This action cannot be easily reversed." -ForegroundColor Yellow
$response = Read-Host "Proceed? (yes/no)"
if ($response -ne 'yes') { Write-Host "Cancelled." -ForegroundColor Red; return }
}
# Enable SDN
Write-Host "`nRunning Add-EceFeature -FeatureName SDN (may take 10-15 minutes)..." -ForegroundColor Yellow
Add-EceFeature -FeatureName "SDN" -Verbose
Write-Host " ✓ SDN feature enabled" -ForegroundColor Green
# Wait for Network Controller
Write-Host "`nWaiting for Network Controller to come online..." -ForegroundColor Yellow
$timeout = 300; $elapsed = 0
while ($elapsed -lt $timeout) {
try {
$nc = Get-ClusterResource | Where-Object { $_.ResourceType -eq "Network Controller" }
if ($nc -and $nc.State -eq "Online") { Write-Host " ✓ Network Controller is online" -ForegroundColor Green; break }
} catch { }
Start-Sleep -Seconds 15; $elapsed += 15
Write-Host " Waiting... ($elapsed s)" -ForegroundColor Gray
}
if ($elapsed -ge $timeout) { Write-Host " ⚠ Timeout — check cluster resources manually" -ForegroundColor Yellow }
Write-Host "`n✅ SDN enablement complete. Next: Configure Network Security Groups." -ForegroundColor Green
This script is completely self-contained. Run it directly on any Azure Local cluster node — no variables.yml, no config-loader, no helpers required.
Verification
After enabling SDN, verify the following:
1. Network Controller Status
# Check Network Controller cluster resource
Get-ClusterResource | Where-Object { $_.ResourceType -eq "Network Controller" }
# Expected output: State = Online
2. Virtual Filtering Extensions
# Check VFP extension on virtual switches
Get-VMSwitch | ForEach-Object {
Get-VMSwitchExtension -VMSwitchName $_.Name |
Where-Object { $_.Name -match "Azure|VFP" } |
Select-Object VMSwitchName, Name, Enabled
}
3. Azure Portal Verification
- Navigate to Azure Portal → Azure Arc → Azure Local
- Select your cluster
- Go to Networking
- Verify Logical Networks section is accessible
Troubleshooting
| Issue | Resolution |
|---|---|
| "Feature not found" | Ensure cluster is version 2601+ |
| "Not connected to Arc" | Run Sync-AzureStackHCI to restore connectivity |
| Network Controller not starting | Check cluster health and event logs |
| VFP extension not enabled | Verify virtual switch configuration |
| "Incompatible SDN deployment" | Cannot enable if on-premises SDN was used previously |
Post-Enablement Notes
After enabling SDN via Arc, you must manage SDN only through:
- Azure Portal
- Azure CLI
- ARM Templates
Do NOT use:
- Windows Admin Center SDN management
- SDN Express scripts
- PowerShell SDN cmdlets for on-premises management
Next Steps
Proceed to Task 3: Configure Network Security Groups.
Navigation
| Previous | Up | Next |
|---|---|---|
| ← Task 01: Validate SDN Prerequisites | Phase 01: SDN Deployment | Task 03: Configure NSGs → |
| Version | Date | Author | Changes |
|---|---|---|---|
| 1.0.0 | 2026-03-24 | Azure Local Cloudnology Team | Initial release |