Monitor: AESFMA verify-before-delete - keep INTERNETACCESS until cert ready

Old gate (SCEP cert in LocalMachine\My with Client Auth EKU) was both
too loose (matches non-AESFMA certs) and unable to verify the cert
chains to GE's RADIUS root. INTERNETACCESS got deleted before AESFMA
could actually authenticate, orphaning the bay.

New flow: when Phase 1 essentials (AAD + Intune + EmTask + baseline)
are complete, ATTEMPT netsh wlan connect AESFMA with INTERNETACCESS
still up as fallback. Wait 8s, parse netsh wlan show interfaces for
SSID=AESFMA + State=connected. Only delete INTERNETACCESS after
operational verification. If AESFMA connect fails (cert not provisioned
yet, RADIUS server unreachable, etc), keep INTERNETACCESS and retry
next tick. Loop runs every 5s while DeviceIdReported is false, so the
swap fires as soon as AESFMA is operationally viable.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-05-14 17:46:19 -04:00
parent a9260ecadd
commit f013aa2bff

View File

@@ -311,39 +311,35 @@ function Get-Phase1 {
# Once Intune registration is fully landed (AAD-joined + Intune-enrolled # Once Intune registration is fully landed (AAD-joined + Intune-enrolled
# + EnterpriseMgmt task present + baseline policies arrived): # + EnterpriseMgmt task present + baseline policies arrived):
# - Push idx=7 to PXE dashboard with the DeviceId / QR. # - Push idx=7 to PXE dashboard with the DeviceId / QR.
# The INTERNETACCESS -> AESFMA WiFi swap is GATED SEPARATELY on the # The INTERNETACCESS -> AESFMA WiFi swap uses a VERIFY-BEFORE-DELETE
# actual SCEP-provisioned machine cert landing in LocalMachine\My # pattern so the bay never ends up with no path:
# with Client Authentication EKU. Phase 1 essentials flip earlier # 1. Phase 1 essentials must be COMPLETE (Intune registration done).
# than the cert delivery, and tearing INTERNETACCESS without the # 2. Attempt netsh wlan connect AESFMA while INTERNETACCESS still up.
# cert present leaves the bay with no path (AESFMA EAP-TLS would # 3. Wait ~8s, parse netsh wlan show interfaces for SSID=AESFMA +
# fail). Wait for the cert before swapping. # State=connected.
# 4. ONLY after operationally connected to AESFMA, delete INTERNETACCESS.
# 5. If connect fails (cert not provisioned yet, etc), keep
# INTERNETACCESS, retry next tick.
$phase1Essential = ($script:cache.AzureAdJoined -and $phase1Essential = ($script:cache.AzureAdJoined -and
$script:cache.IntuneEnrolled -and $script:cache.IntuneEnrolled -and
$script:cache.EmTaskExists -and $script:cache.EmTaskExists -and
$policiesBaselineReady) $policiesBaselineReady)
if (-not $script:cache.InternetAccessDeleted) { if ($phase1Essential -and -not $script:cache.InternetAccessDeleted) {
# Look for any LocalMachine\My cert with Client Auth EKU
# (1.3.6.1.5.5.7.3.2). That's what AESFMA EAP-TLS uses.
$hasMachineClientAuthCert = $false
try { try {
$clientAuthEku = '1.3.6.1.5.5.7.3.2' Write-Host "Phase 1 essentials complete - attempting AESFMA join (verify-before-delete)..."
$hasMachineClientAuthCert = [bool](Get-ChildItem 'Cert:\LocalMachine\My' -ErrorAction SilentlyContinue | $null = netsh wlan connect name="AESFMA" ssid="AESFMA" 2>&1 | Out-String
Where-Object { Start-Sleep -Seconds 8
$_.EnhancedKeyUsageList.ObjectId -contains $clientAuthEku $wlanState = netsh wlan show interfaces 2>$null | Out-String
} | Select-Object -First 1) if ($wlanState -match '(?ms)SSID\s*:\s*AESFMA.*?State\s*:\s*connected') {
} catch {} Write-Host "AESFMA connected. Deleting INTERNETACCESS profile..."
if ($hasMachineClientAuthCert) {
try {
Write-Host "SCEP machine cert detected - swapping WiFi: delete INTERNETACCESS, connect AESFMA..."
$delOut = netsh wlan delete profile name="INTERNETACCESS" 2>&1 | Out-String $delOut = netsh wlan delete profile name="INTERNETACCESS" 2>&1 | Out-String
Write-Host $delOut Write-Host $delOut
Start-Sleep -Seconds 2
$conOut = netsh wlan connect name="AESFMA" ssid="AESFMA" 2>&1 | Out-String
Write-Host $conOut
$script:cache.InternetAccessDeleted = $true $script:cache.InternetAccessDeleted = $true
} catch { } else {
Write-Warning "WiFi swap (INTERNETACCESS -> AESFMA) failed: $_" Write-Host "AESFMA connect not yet operational - keeping INTERNETACCESS, will retry next tick."
} }
} catch {
Write-Warning "AESFMA verify-before-delete attempt failed: $_"
} }
} }
# idx=7 push fires AS SOON AS DeviceId is captured. We want the QR # idx=7 push fires AS SOON AS DeviceId is captured. We want the QR