Skip to main content
Version: Next

Task 04: Disable DHCP on All Adapters

Runbook Azure Dell

DOCUMENT CATEGORY: Runbook SCOPE: Network DHCP configuration PURPOSE: Lock static IP configuration by disabling DHCP on all physical adapters while preserving DHCP on NDIS, Hyper-V virtual, and other excluded adapter types MASTER REFERENCE: Phase 03: OS Configuration

Status: Active


Overview

Disable DHCP on all network adapters on each Azure Local node, except adapters matching the exclusion pattern. This permanently locks in the static IP configured in Task 03 and prevents any adapter from requesting DHCP renewals.

Run AFTER Task 03

Task 03 must be complete and the management static IP verified on every node before running this task. If DHCP is disabled before static IP is set, the node will lose connectivity.

What the scripts do:

  1. Enumerate all NetAdapter entries on the node
  2. Skip adapters whose InterfaceDescription matches the exclusion pattern
  3. Skip adapters with no IPv4 interface (nothing to configure)
  4. Check idempotency — already-disabled adapters are logged as OK, not re-processed
  5. Call Set-NetIPInterface -Dhcp Disabled on each remaining adapter
  6. Verify the change and log a final results table

Why exclude certain adapters?

Excluded patternAdapter typeWhy DHCP is preserved
NDISRemote NDIS Compatible DeviceUSB/virtual management channel — may use DHCP for out-of-band access
Hyper-V VirtualHyper-V Virtual Ethernet AdapterPost-cluster vEthernet adapters require DHCP for vSwitch functionality
WAN MiniportVPN / routing tunnelsNo meaningful physical IPv4 assignment
BluetoothBluetooth PAN adapterNot used for cluster networking
Wi-Fi DirectWi-Fi Direct virtual adapterNot used for cluster networking
Microsoft Kernel DebugKernel debug network adapterReserved for debug use
MultiplexorMicrosoft Network Adapter MultiplexorUsed by NIC teaming — managed separately
Phase 03 adapter state

At this phase, Hyper-V is not yet deployed — no vEthernet adapters exist yet. The Hyper-V Virtual pattern is included defensively so the script remains safe to re-run after cluster deployment.


Prerequisites

RequirementDescriptionSource
Task 03 completeStatic IP configured and verified on all nodesTask 03: Configure Static IP
Node accessibleReachable via static management IPNetwork validation
Admin credentialsLocal admin (direct) or domain admin (orchestrated)Deployment credentials

Configuration Reference

The variables.yml path used by the orchestrated script:

yml PathUsed forExample
nodes.<name>.management_ipPSRemoting target IP (management NIC static)10.100.200.11

The exclusion pattern is defined in #region CONFIGURATION of both scripts. No other values are read from variables.yml — this task does not modify networking parameters, only disables DHCP.


Execution Options

Run on each node individually — via RDP, console, or KVM.

Toolkit script: scripts/deploy/04-cluster-deployment/phase-03-os-configuration/task-04-disable-dhcp-on-management-adapter/powershell/Disable-DHCPOnAllAdapters.ps1

Configuration block (edit before running):

VariableDescriptionDefault
$ExcludePatternRegex pattern — adapters matching this are skippedNDIS|Hyper-V Virtual|WAN Miniport|Bluetooth|Wi-Fi Direct|Microsoft Kernel Debug|Multiplexor
Disable-DHCPOnAllAdapters.ps1
#Requires -Version 5.1
<#
.SYNOPSIS
Disable-DHCPOnAllAdapters.ps1
Disables DHCP on all network adapters except virtual/management adapters.

.DESCRIPTION
Run directly on each Azure Local node (locally or via PSRemoting).
Disables DHCP on every physical NIC. Adapters whose InterfaceDescription
matches the $ExcludePattern are skipped — this preserves DHCP on Remote NDIS
and Hyper-V virtual adapters.

Why exclude NDIS / virtual adapters:
- Remote NDIS Compatible Device: USB or virtual management NIC — should keep DHCP
- Hyper-V Virtual Ethernet Adapter: post-cluster vEthernet — must keep DHCP
- WAN Miniport: VPN/routing tunnels — no meaningful IPv4 interface to set

Behaviour:
- Skips adapters matching $ExcludePattern in InterfaceDescription
- Skips adapters with no IPv4 interface (nothing to configure)
- Checks idempotency — already-disabled adapters are reported as OK, not re-set
- Logs a final table of every adapter: Name, Description, Status, DHCP result

.NOTES
Author: Azure Local Cloud Azure Local Cloud
Version: 1.0.0
Phase: 03-os-configuration
Task: task-04-disable-dhcp-on-management-adapter
Execution: Run directly on the node (console, KVM, RDP, or PSRemoting)
Prerequisites: PowerShell 5.1+, local admin rights
Run after: Task 03 — static IP must already be configured on management NIC

.EXAMPLE
.\Disable-DHCPOnAllAdapters.ps1
#>

# ============================================================================
#region CONFIGURATION
# Adapters whose InterfaceDescription matches ANY of these patterns will be SKIPPED.
# Add patterns here to protect additional virtual or management adapters.
# ============================================================================

$ExcludePattern = "NDIS|Hyper-V Virtual|WAN Miniport|Bluetooth|Wi-Fi Direct|Microsoft Kernel Debug|Multiplexor"

#endregion CONFIGURATION
# ============================================================================

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Write-Log {
param([string]$Message, [string]$Level = "INFO")
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$color = switch ($Level) {
"ERROR" { "Red" }
"WARN" { "Yellow" }
"SUCCESS" { "Green" }
"HEADER" { "Cyan" }
"SKIP" { "DarkGray" }
default { "White" }
}
Write-Host "[$timestamp] [$Level] $Message" -ForegroundColor $color
}

# ============================================================================
# MAIN
# ============================================================================

try {
Write-Log "=== Disable-DHCPOnAllAdapters.ps1 ===" "HEADER"
Write-Log "Node: $($env:COMPUTERNAME)"
Write-Log "Exclude pattern: $ExcludePattern"

$adapters = Get-NetAdapter | Sort-Object Name

if ($adapters.Count -eq 0) {
Write-Log "No network adapters found." "WARN"
exit 0
}

Write-Log "Adapters found: $($adapters.Count)"

$results = [System.Collections.Generic.List[PSCustomObject]]::new()

foreach ($adapter in $adapters) {
$desc = $adapter.InterfaceDescription
$name = $adapter.Name
$status = $adapter.Status

# Check exclude pattern
if ($desc -match $ExcludePattern) {
Write-Log " SKIP $name ($desc)" "SKIP"
$results.Add([PSCustomObject]@{
Name = $name
Description = $desc
Status = $status
DHCP = "Skipped (excluded)"
Result = "Skipped"
})
continue
}

# Get IPv4 interface — some adapters have no IPv4 interface
$ipIface = Get-NetIPInterface -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
if (-not $ipIface) {
Write-Log " SKIP $name (no IPv4 interface)" "SKIP"
$results.Add([PSCustomObject]@{
Name = $name
Description = $desc
Status = $status
DHCP = "N/A (no IPv4)"
Result = "Skipped"
})
continue
}

# Idempotency check
if ($ipIface.Dhcp -eq "Disabled") {
Write-Log " OK $name (already Disabled)" "SUCCESS"
$results.Add([PSCustomObject]@{
Name = $name
Description = $desc
Status = $status
DHCP = "Disabled"
Result = "AlreadyDisabled"
})
continue
}

# Disable DHCP
try {
Write-Log " SET $name ($status) $($ipIface.Dhcp) -> Disabled"
Set-NetIPInterface -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4 -Dhcp Disabled -ErrorAction Stop

# Verify
$afterIface = Get-NetIPInterface -InterfaceIndex $adapter.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
if ($afterIface.Dhcp -eq "Disabled") {
Write-Log " OK $name DHCP disabled" "SUCCESS"
$results.Add([PSCustomObject]@{
Name = $name
Description = $desc
Status = $status
DHCP = "Disabled"
Result = "Changed"
})
} else {
Write-Log " FAIL $name DHCP is still $($afterIface.Dhcp)" "WARN"
$results.Add([PSCustomObject]@{
Name = $name
Description = $desc
Status = $status
DHCP = $afterIface.Dhcp
Result = "Failed"
})
}
} catch {
Write-Log " ERROR $name $_" "ERROR"
$results.Add([PSCustomObject]@{
Name = $name
Description = $desc
Status = $status
DHCP = "Error"
Result = "Error: $_"
})
}
}

# Final summary table
Write-Log "=== RESULTS ===" "HEADER"
$results | Format-Table -AutoSize | Out-String | Write-Host

$failed = @($results | Where-Object { $_.Result -notin @("Changed","AlreadyDisabled","Skipped") })
if ($failed.Count -gt 0) {
Write-Log "$($failed.Count) adapter(s) failed. Review errors above." "WARN"
exit 1
}

$changed = @($results | Where-Object { $_.Result -eq "Changed" }).Count
$already = @($results | Where-Object { $_.Result -eq "AlreadyDisabled" }).Count
$skipped = @($results | Where-Object { $_.Result -eq "Skipped" }).Count
Write-Log "Changed: $changed Already disabled: $already Skipped: $skipped" "SUCCESS"
Write-Log "DHCP DISABLE COMPLETE" "SUCCESS"
exit 0

} catch {
Write-Log "CRITICAL ERROR: $_" "ERROR"
exit 1
}

Expected output (excerpt):

[2026-03-05 09:10:01] [HEADER] === Disable-DHCPOnAllAdapters.ps1 ===
[2026-03-05 09:10:01] [INFO] Node: AZL-NODE-01
[2026-03-05 09:10:01] [INFO] Exclude pattern: NDIS|Hyper-V Virtual|WAN Miniport|Bluetooth|Wi-Fi Direct|Microsoft Kernel Debug|Multiplexor
[2026-03-05 09:10:01] [INFO] Adapters found: 5
[2026-03-05 09:10:01] [SKIP] SKIP Ethernet (Remote NDIS Compatible Device)
[2026-03-05 09:10:01] [INFO] SET Embedded NIC 1 (Up) Enabled -> Disabled
[2026-03-05 09:10:02] [SUCCESS] OK Embedded NIC 1 DHCP disabled
[2026-03-05 09:10:02] [INFO] SET Embedded NIC 2 (Disconnected) Enabled -> Disabled
[2026-03-05 09:10:02] [SUCCESS] OK Embedded NIC 2 DHCP disabled
[2026-03-05 09:10:02] [INFO] SET Embedded NIC 3 (Up) Enabled -> Disabled
[2026-03-05 09:10:03] [SUCCESS] OK Embedded NIC 3 DHCP disabled
[2026-03-05 09:10:03] [INFO] SET Embedded NIC 4 (Up) Enabled -> Disabled
[2026-03-05 09:10:03] [SUCCESS] OK Embedded NIC 4 DHCP disabled
[2026-03-05 09:10:03] [HEADER] === RESULTS ===

Name Description Status DHCP Result
---- ----------- ------ ---- ------
Embedded NIC 1 Intel(R) Ethernet Connection 25G 4P E823-C LOM Up Disabled Changed
Embedded NIC 2 Intel(R) Ethernet Connection 25G 4P E823-C LOM Disconnected Disabled Changed
Embedded NIC 3 Intel(R) Ethernet Connection 25G 4P E823-C LOM Up Disabled Changed
Embedded NIC 4 Intel(R) Ethernet Connection 25G 4P E823-C LOM Up Disabled Changed
Ethernet Remote NDIS Compatible Device Up Skipped (excluded) Skipped

[2026-03-05 09:10:03] [SUCCESS] Changed: 4 Already disabled: 0 Skipped: 1
[2026-03-05 09:10:03] [SUCCESS] DHCP DISABLE COMPLETE

Validation

Verify DHCP is disabled on all physical adapters across all nodes:

# Run on each node (or orchestrate with PSRemoting)
Get-NetAdapter | ForEach-Object {
$iface = Get-NetIPInterface -InterfaceIndex $_.ifIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
[PSCustomObject]@{
Name = $_.Name
Description = $_.InterfaceDescription
Status = $_.Status
DHCP = $iface.Dhcp
IsExcluded = $_.InterfaceDescription -match "NDIS|Hyper-V Virtual|WAN Miniport"
}
} | Format-Table -AutoSize

Validation checklist:

CheckExpectedStatus
Physical adapters — DHCPDisabled
NDIS / excluded adapters — DHCPEnabled (or N/A)
Management NIC reachableAll nodes respond to ping
No connectivity lossContinuous management access
Disconnected adapters

Disconnected adapters may show blank or Enabled DHCP status. This is acceptable — they are not active on the network and cannot obtain an address even with DHCP nominally enabled.


Troubleshooting

IssueRoot CauseRemediation
DHCP re-enabled after rebootGroup Policy overrideCheck GPO DHCP settings; apply exception or override in policy
Adapter still showing Enabled after scriptScript exited with non-zeroReview output log; rerun script and check for errors
Connectivity lost after runningScript disabled DHCP on management NIC before static IP was setRe-run Task 03 first; boot node via console or iDRAC
Set-NetIPInterface access deniedScript not run as local adminRelaunch PowerShell as Administrator
Orchestrated script: No infrastructure*.yml foundConfig file not in search pathPass -ConfigPath explicitly: .\Invoke-DisableDHCP-Orchestrated.ps1 -ConfigPath C:\path\to\variables.yml
Orchestrated script: management_ip not foundNode entry missing management_ip in ymlVerify nodes.<name>.management_ip is populated in variables.yml
Node cannot be reached via PSRemotingWinRM not configuredRun Enable-PSRemoting -Force on the node (Task 02 enables RDP — verify WinRM separately)

Task 03: Configure Static IP↑ Phase 03: OS ConfigurationTask 05: Configure DNS Servers →

Version Control

VersionDateAuthorChanges
1.02026-01-31Azure Local Cloud Azure Local CloudnologyInitial document
2.02026-03-05Azure Local Cloud Azure Local CloudnologyFull rewrite to standards — complete frontmatter, 2-tab structure (Direct + Orchestrated), Standalone tab removed, full embedded scripts, NDIS defensive pattern, variables.yml integration in orchestrated script