From 2b730969dd853d87c4a38b9dc24a2526866d2deb Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 13 May 2026 12:26:43 -0400 Subject: [PATCH] migrate-to-wifi: restore wired-disable behavior Reverts the 2026-04-24 no-op stub. Empirically the gateway-suppression fix (dnsmasq dhcp-option=3/=6 empty) alone is NOT sufficient to keep Windows from using the wired NIC for Intune Device Configuration / DSC traffic. Even with no default route on wired AND the unattend's InterfaceMetric trick (WiFi=10, Wired=100), the bay stalls on the DSC phase until the wired cable is physically unplugged. Restoring the prior body that disables non-WiFi NICs at first logon post-PPKG. Gated on Get-NetAdapter for a Wi-Fi/Wireless/WLAN/802.11 adapter - towers without WiFi stay on ethernet (the only-NIC scenario where disabling would hang first logon). Falls back to re-enabling ethernet if login.microsoftonline.us:443 doesn't respond within 5 min. Monitor-IntuneProgress.ps1 already has the symmetric re-enable ("Re-enable any wired NICs that Order 5 disabled") at the start of its monitor loop, which kicks in after DSC creds land. Net effect: wired disabled during the DSC fetch window, re-enabled by the time eDNC autostart needs the local NIC. Co-Authored-By: Claude Opus 4.7 (1M context) --- playbook/migrate-to-wifi.ps1 | 67 +++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/playbook/migrate-to-wifi.ps1 b/playbook/migrate-to-wifi.ps1 index babf163..be803f0 100644 --- a/playbook/migrate-to-wifi.ps1 +++ b/playbook/migrate-to-wifi.ps1 @@ -1,30 +1,43 @@ -# migrate-to-wifi.ps1 - No-op as of 2026-04-24. +# migrate-to-wifi.ps1 - Invoked by FlatUnattendW10-shopfloor.xml as Order 5 +# during first logon, right after wait-for-internet.ps1 and right before +# GCCH enrollment. Moves the machine off wired onto WiFi for the rest of +# the imaging chain so the PXE ethernet cable can be safely disconnected. # -# Previously this disabled all wired NICs at first logon to keep PPKG / -# Intune enrollment routing internet traffic via WiFi. The wired NIC was -# preferred by Windows because the PXE dnsmasq was handing out a default -# gateway (dhcp-option=3,10.9.100.1) which Windows installed as a default -# route, and the lower interface metric of wired beat WiFi. Internet-bound -# traffic then black-holed at 10.9.100.1 (the PXE server, which doesn't -# forward). -# -# That root cause was fixed by removing the dhcp-option=3 and =6 lines -# from /etc/dnsmasq.conf on the PXE server. Without an advertised gateway -# on the PXE side, Windows can't add a default route via wired, so all -# internet traffic uses WiFi by default and the wired NIC stays harmless -# for same-subnet PXE/SMB traffic to 10.9.100.1. -# -# Side effect of the original behavior was an eDNC race: eDNC autostart -# would fire while the wired NIC was still disabled and hit WSAEINVAL -# (Winsock 10022) trying to bind to a non-existent local IP, looping its -# retry timer until a SYSTEM task re-enabled the NIC after SFLD creds -# landed (often ~30+ min later). Keeping the NIC up the whole time -# eliminates that race. -# -# Kept as a no-op file (instead of removed) so the unattend XML's Order 5 -# RunSynchronousCommand entry does not need to be re-numbered. If the -# dhcp-option lines ever come back, this can be reverted to the disable -# logic by restoring from git. +# Gated: if there is no physical Wi-Fi adapter on the machine (tower / +# desktop case), the whole migration is a no-op. Previously this step +# disabled all wired adapters unconditionally and then waited for WiFi +# internet that could never arrive on towers, hanging first logon forever. -Write-Host 'migrate-to-wifi.ps1: no-op (wired NIC kept enabled).' +$wifi = Get-NetAdapter -Physical -ErrorAction SilentlyContinue | + Where-Object { $_.InterfaceDescription -match 'Wi-?Fi|Wireless|WLAN|802\.11' } + +if (-not $wifi) { + Write-Host 'No WiFi adapter - staying on ethernet.' -ForegroundColor Cyan + exit 0 +} + +Get-NetAdapter -Physical | + Where-Object { $_.InterfaceDescription -notmatch 'Wi-?Fi|Wireless|WLAN|802\.11' } | + Disable-NetAdapter -Confirm:$false + +$deadline = (Get-Date).AddMinutes(5) +$ok = $false +while ((Get-Date) -lt $deadline) { + try { + if (Test-NetConnection -ComputerName login.microsoftonline.us -Port 443 -InformationLevel Quiet -WarningAction SilentlyContinue) { + $ok = $true + break + } + } catch {} + Start-Sleep -Seconds 5 +} + +if ($ok) { + Write-Host 'Internet confirmed over WiFi.' -ForegroundColor Green +} else { + Write-Host 'WiFi internet timeout - re-enabling ethernet.' -ForegroundColor Yellow + Get-NetAdapter -Physical | + Where-Object { $_.InterfaceDescription -notmatch 'Wi-?Fi|Wireless|WLAN|802\.11' } | + Enable-NetAdapter -Confirm:$false +} exit 0