From a17b3fae6af0d288dcee73c79aa45da870cf0b2b Mon Sep 17 00:00:00 2001 From: cproudlock Date: Thu, 14 May 2026 16:45:54 -0400 Subject: [PATCH] Retire wired-disable/re-enable dance now that PXE LAN is 172.16.9.0/24 GE Report IP filters Get-NetIPAddress on StartsWith("10.") and PXE LAN addresses are now 172.16.9.x which the filter skips naturally. The disable-then-re-enable workaround was only needed when PXE LAN was 10.9.100.x and bays leaked that IP to the GE webhook. With the renumber that whole flow is dead weight. Removed: - playbook/shopfloor-setup/Shopfloor/lib/Disable-WiredNics.ps1 (file) - Run-ShopfloorSetup: Disable-WiredNics call after PPKG returns - Run-ShopfloorSetup: "GE Re-enable Wired NICs" SYSTEM task registration - Monitor-IntuneProgress: reportIpLog-gated wired re-enable + idx=7 retry - Monitor-IntuneProgress: reportIpDone gate on Phase 1 done check Side benefit: stages 2-6 dashboard pushes no longer go dark mid-flow (used to die between idx=6 and idx=7 when wired was off). Phase 1 row on the Monitor screen now flips COMPLETE on the natural AAD + Intune + EmTask + baseline-policies condition instead of waiting on the Report IP log file. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../shopfloor-setup/Run-ShopfloorSetup.ps1 | 77 +------------------ .../Shopfloor/lib/Disable-WiredNics.ps1 | 45 ----------- .../Shopfloor/lib/Monitor-IntuneProgress.ps1 | 73 ++---------------- 3 files changed, 12 insertions(+), 183 deletions(-) delete mode 100644 playbook/shopfloor-setup/Shopfloor/lib/Disable-WiredNics.ps1 diff --git a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 index 2c8072b..5a5c5da 100644 --- a/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 +++ b/playbook/shopfloor-setup/Run-ShopfloorSetup.ps1 @@ -299,63 +299,10 @@ if (Test-Path -LiteralPath $monitorScript) { # These run on every logon regardless of PC type, mounting the SFLD share # for version-pinned app enforcement. Initial install already handled by # preinstall flow; enforcers only kick in when detection fails. -# --- Re-enable wired NICs once lockdown completes (Phase 6) --- -# migrate-to-wifi.ps1 disables wired NICs so the PPKG runs over WiFi. -# Keep them disabled through the entire Intune sync + DSC + lockdown -# chain so nothing interrupts the WiFi-based enrollment. Only re-enable -# after lockdown lands (Autologon_Remediation.log confirms ShopFloor -# autologon set). Monitor-IntuneProgress runs as Limited and can't call -# Enable-NetAdapter (needs admin). This SYSTEM task fires at logon, -# polls for lockdown completion, re-enables wired NICs, and self-deletes. -$reEnableTask = 'GE Re-enable Wired NICs' -try { - $script = @' -# Poll for the GE Report-IP Proactive Remediation log file. Its appearance -# means the Report IP script has fired with WiFi-only IPs (because we -# disabled wired post-PPKG) - which is the exact moment we want to bring -# wired back up so Monitor-IntuneProgress can push idx=7 with the -# DeviceId / QR code before the Intune-triggered LAPS-prompt reboot lands. -# Extension is .LOG (not .txt) observed in field; match any extension. -$ip = Get-ChildItem 'C:\Logs\GE_Report_IP_Address*' -ErrorAction SilentlyContinue | Select-Object -First 1 -if (-not $ip) { exit 0 } - -# Vendor-agnostic wired-NIC re-enable. NetAdapter "Name" varies wildly -# ("Ethernet", "Ethernet 2", "Network", per-vendor names like "Realtek -# Gaming GbE", "Intel(R) Ethernet Connection (10) I219-V") so filtering -# by Name is unreliable. Filter by PhysicalMediaType instead, with a -# keyword-negative guard for drivers that mis-report PhysicalMediaType. -# Captures Realtek, Intel, Broadcom, Marvell, Aquantia, etc. -Get-NetAdapter -Physical -ErrorAction SilentlyContinue | - Where-Object { - $_.HardwareInterface -eq $true -and - $_.PhysicalMediaType -ne 'Native 802.11' -and - $_.PhysicalMediaType -ne 'Wireless WAN' -and - $_.PhysicalMediaType -ne 'BlueTooth' -and - $_.InterfaceDescription -notmatch '(?i)Wi-?Fi|Wireless|WLAN|802\.11|Bluetooth' - } | - Enable-NetAdapter -Confirm:$false -ErrorAction SilentlyContinue -Unregister-ScheduledTask -TaskName 'GE Re-enable Wired NICs' -Confirm:$false -ErrorAction SilentlyContinue -'@ - $scriptPath = 'C:\Program Files\GE\ReEnableNIC.ps1' - if (-not (Test-Path 'C:\Program Files\GE')) { - New-Item -Path 'C:\Program Files\GE' -ItemType Directory -Force | Out-Null - } - Set-Content -Path $scriptPath -Value $script -Force - - $reEnableAction = New-ScheduledTaskAction -Execute 'powershell.exe' ` - -Argument "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" - $reEnableTrigger = New-ScheduledTaskTrigger -AtLogOn - $reEnableTrigger.Repetition = (New-ScheduledTaskTrigger -Once -At (Get-Date) ` - -RepetitionInterval (New-TimeSpan -Minutes 5)).Repetition - $reEnablePrincipal = New-ScheduledTaskPrincipal -UserId 'SYSTEM' -LogonType ServiceAccount -RunLevel Highest - $reEnableSettings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries ` - -ExecutionTimeLimit (New-TimeSpan -Minutes 2) - Register-ScheduledTask -TaskName $reEnableTask -Action $reEnableAction -Trigger $reEnableTrigger ` - -Principal $reEnablePrincipal -Settings $reEnableSettings -Force -ErrorAction Stop | Out-Null - Write-Host "Registered '$reEnableTask' task (waits for SFLD creds, then re-enables wired NICs)." -} catch { - Write-Warning "Failed to register NIC re-enable task: $_" -} +# Wired-disable / re-enable dance retired after PXE LAN renumber to +# 172.16.9.0/24. GE Report IP filters Get-NetIPAddress on StartsWith("10.") +# so PXE LAN addresses are no longer caught - wired NIC can stay up +# through the whole imaging chain without leaking to the GE webhook. $commonSetupDir = Join-Path $setupDir 'common' @@ -479,24 +426,8 @@ if (Test-Path -LiteralPath $enrollScript) { try { Stop-Transcript | Out-Null } catch {} & $enrollScript - # idx=6 push happens BEFORE wired disable so the dashboard captures - # the handoff stage. Disable-WiredNics comes right after - kills wired - # before PostPpkg settle's Schedule #3 hammer hits Intune endpoints, - # before the PPKG-driven reboot, and before IME starts firing the - # Report IP script. Goal: GE's Report IP webhook only ever sees the - # corp-WiFi IP, never PXE LAN (10.9.100.x). Monitor-IntuneProgress - # re-enables wired once C:\Logs\GE_Report_IP_Address*.txt shows up - # (proof of clean Report IP fire) and then pushes idx=7. Write-Host "" Report-Stage -Stage 'Run-ShopfloorSetup: handoff to Monitor-IntuneProgress' -Index 6 - - $disableWiredScript = Join-Path $PSScriptRoot 'shopfloor-setup\Shopfloor\lib\Disable-WiredNics.ps1' - if (Test-Path -LiteralPath $disableWiredScript) { - try { & $disableWiredScript } catch { Write-Warning "Disable-WiredNics threw: $_" } - } else { - Write-Warning "Disable-WiredNics.ps1 not found at $disableWiredScript - wired stays up (Report IP leak risk)" - } - Write-Host "=== Handing off to Monitor-IntuneProgress -PostPpkg ===" cmd /c "shutdown /a 2>nul" | Out-Null $monitor = Join-Path $setupDir 'Shopfloor\lib\Monitor-IntuneProgress.ps1' diff --git a/playbook/shopfloor-setup/Shopfloor/lib/Disable-WiredNics.ps1 b/playbook/shopfloor-setup/Shopfloor/lib/Disable-WiredNics.ps1 deleted file mode 100644 index 0e922b8..0000000 --- a/playbook/shopfloor-setup/Shopfloor/lib/Disable-WiredNics.ps1 +++ /dev/null @@ -1,45 +0,0 @@ -# Disable-WiredNics.ps1 -# Disables every Up wired (MediaType 802.3) NIC and records their names to -# C:\Enrollment\disabled-wired-nics.txt so Monitor-IntuneProgress can -# re-enable them once Report IP has run on WiFi-only. -# -# Reason: GE's Intune Proactive-Remediation "Report IP" script enumerates -# Get-NetIPAddress and POSTs every IP it finds to a GE webhook. When a -# shopfloor bay is still cabled to the air-gapped PXE LAN (172.16.9.0/24), -# the webhook sees 10.9.100.x as one of the device's IPs and tags the bay -# "not on corp net". A dynamic group / assignment-filter at GE then excludes -# the bay from receiving the SFLD ConfigurationProfile (Function + SasToken -# OMA-URI) -> Phase 2 "Device Configuration" never closes. -# -# Killing the wired NIC after stage 2 reports + before AAD-join makes the -# bay's first Report IP fire see corp-WiFi IP only. The bay is tagged -# clean, dynamic group eligibility flips, SFLD policy delivers normally. -# Monitor-IntuneProgress re-enables the NIC once Report IP's log file -# appears at C:\Logs\GE_Report_IP_Address*.txt. - -$ErrorActionPreference = 'Continue' -$stateFile = 'C:\Enrollment\disabled-wired-nics.txt' - -try { - $wired = Get-NetAdapter -ErrorAction Stop | - Where-Object { - $_.Status -eq 'Up' -and - $_.MediaType -eq '802.3' -and - $_.HardwareInterface -eq $true - } - - if (-not $wired) { - Write-Host "Disable-WiredNics: no Up wired NICs found - nothing to disable." - return - } - - $names = $wired | ForEach-Object { $_.Name } - $names | Out-File -FilePath $stateFile -Encoding ASCII -Force - Write-Host ("Disable-WiredNics: persisted {0} NIC name(s) -> {1}" -f $names.Count, $stateFile) - foreach ($n in $names) { Write-Host " - $n" } - - $wired | Disable-NetAdapter -Confirm:$false -ErrorAction Continue - Write-Host "Disable-WiredNics: NICs disabled. Re-enable triggered by Monitor when GE_Report_IP_Address log appears." -} catch { - Write-Warning "Disable-WiredNics: failed: $_" -} diff --git a/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 b/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 index 3fee7dc..2cb31e5 100644 --- a/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 @@ -223,61 +223,12 @@ function Get-Phase1 { } catch {} } - # Report IP log presence drives two independent actions that USED to be - # bundled inside the DeviceId-push gate. Splitting them so re-enable - # fires even if DeviceId hasn't been captured yet (e.g. AAD join lag, - # dsregcmd parse miss): - # - # 1. Re-enable wired NICs as soon as the log lands + state file exists. - # 2. Push idx=7 once DeviceId is captured AND the log exists. - $reportIpLog = Get-ChildItem -Path 'C:\Logs\GE_Report_IP_Address*' -ErrorAction SilentlyContinue | - Select-Object -First 1 - $nicListFile = 'C:\Enrollment\disabled-wired-nics.txt' - $justReEnabled = $false - if ($reportIpLog -and (Test-Path $nicListFile)) { - try { - $nicNames = Get-Content $nicListFile -ErrorAction Stop - foreach ($n in $nicNames) { - if ([string]::IsNullOrWhiteSpace($n)) { continue } - try { Enable-NetAdapter -Name $n -Confirm:$false -ErrorAction Stop } - catch { Write-Warning "Enable-NetAdapter '$n' failed: $_" } - } - # Wait for DHCP renewal + route table update + reachability to - # PXE server. 1 second wasn't enough in field testing - the - # subsequent idx=7 push fired into the void before the wired - # NIC was carrying traffic. - Start-Sleep -Seconds 5 - Remove-Item $nicListFile -Force -ErrorAction SilentlyContinue - $justReEnabled = $true - } catch { - Write-Warning "Re-enable wired NICs failed: $_" - } - } - - # Push DeviceId / idx=7 once, when both DeviceId is captured and the - # Report IP log has landed (dashboard QR renders from DeviceId). - # Retry up to 6x with backoff because the imminent LAPS-prompt reboot - # gives us only seconds and the wired NIC may still be settling. - if ($script:cache.DeviceId -and -not $script:cache.DeviceIdReported -and $reportIpLog) { - Ensure-SendPxeStatus - if (Get-Command Send-PxeStatus -ErrorAction SilentlyContinue) { - $attempts = if ($justReEnabled) { 6 } else { 1 } - for ($i = 0; $i -lt $attempts; $i++) { - $err = $null - try { - Send-PxeStatus -Stage 'Monitor-IntuneProgress: Intune Device ID captured' ` - -StageIndex 7 -StageTotal 8 ` - -IntuneDeviceId $script:cache.DeviceId -ErrorAction Stop - $script:cache.DeviceIdReported = $true - break - } catch { $err = $_ } - if ($i -lt $attempts - 1) { Start-Sleep -Seconds 2 } - } - if (-not $script:cache.DeviceIdReported -and $err) { - Write-Warning "idx=7 push failed after $attempts attempts: $err" - } - } - } + # idx=7 push happens later in Get-Phase1 when Intune-registration + # essentials are all green (see WiFi-swap block). The legacy + # wired-NIC re-enable + reportIpLog-gated idx=7 retry was retired + # after the PXE LAN renumber to 172.16.9.0/24 - PXE LAN addresses + # no longer pass GE Report IP's StartsWith("10.") filter, so the + # wired-disable / re-enable dance is unnecessary. # Lockdown-applied auto-completion. Fleet-wide reality: bays use a LOCAL # ShopFloor account, so AzureAdPrt stays NO and user-scoped Intune policies @@ -863,21 +814,13 @@ function Format-Snapshot { # not just "arriving". Stops the category prompt firing pre-first-reboot # when only ~4 subkeys are present (we tested this empirically; clicking # "assign category" at 4 subkeys = imaging stalls + re-image required). - # Report IP log presence is part of Phase 1 completion. Without that log - # we know GE's Proactive-Remediation script hasn't fired on WiFi-only - # yet, which means the SFLD ConfigurationProfile assignment filter still - # sees a leaked 10.9.100.x IP and Phase 2 won't unblock. Don't call - # registration "done" until Report IP has cleared. - $reportIpDone = [bool](Get-ChildItem -Path 'C:\Logs\GE_Report_IP_Address*' -ErrorAction SilentlyContinue | Select-Object -First 1) $p1Done = ($Snap.Phase1.AzureAdJoined -and $Snap.Phase1.IntuneEnrolled -and - $Snap.Phase1.EmTaskExists -and $Snap.Phase1.PoliciesBaselineReady -and - $reportIpDone) + $Snap.Phase1.EmTaskExists -and $Snap.Phase1.PoliciesBaselineReady) $p1Status = Get-PhaseStatus @( @{ Ok = $Snap.Phase1.AzureAdJoined; Failed = $false }, @{ Ok = $Snap.Phase1.IntuneEnrolled; Failed = $false }, @{ Ok = $Snap.Phase1.EmTaskExists; Failed = $false }, - @{ Ok = $Snap.Phase1.PoliciesBaselineReady; Failed = $false }, - @{ Ok = $reportIpDone; Failed = $false } + @{ Ok = $Snap.Phase1.PoliciesBaselineReady; Failed = $false } ) # Phase 6 / Lockdown (shared by both flows, rendered last).