From 44bbd23e4d71f59445b9e9973b88f8b1bc5efffc Mon Sep 17 00:00:00 2001 From: cproudlock Date: Wed, 13 May 2026 15:47:23 -0400 Subject: [PATCH] Monitor-IntuneProgress: auto-fire idx=8 on lockdown detection Local-user shopfloor fleet (ShopFloor is a LOCAL account) means AzureAdPrt stays NO, user-scoped Intune policies never deliver, and the natural completion gate (baseline policies >= 5 + DSCInstall success + Phase 4 wrappers) never closes. Dashboard sessions stuck at 7/8 / 87.5% forever even though the bay is functionally complete. Real-world definition of "done" for these bays is lockdown applied. Add a per-tick check in Get-Phase1 (alongside the DeviceId push) that detects either: * Winlogon DefaultUserName -like 'ShopFloor*' AND AutoAdminLogon=1 * OR C:\Enrollment\force-lockdown-applied.txt marker file When either is present and not yet pushed, fire Send-PxeStatus StageIndex=8 / StageTotal=8 / Status='succeeded' with the captured IntuneDeviceId for the dashboard QR. One-shot per session via the LockdownCompletePushed cache flag. No need for the operator to run mark-complete.bat anymore - Monitor's main loop will fire idx=8 within ~5s of force-lockdown or autologon flip. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../Shopfloor/lib/Monitor-IntuneProgress.ps1 | 53 ++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 b/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 index 92d8ed4..731d43a 100644 --- a/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 +++ b/playbook/shopfloor-setup/Shopfloor/lib/Monitor-IntuneProgress.ps1 @@ -180,12 +180,13 @@ function Format-Age { # revert once true, so we only re-check until they pass. # ============================================================================ $script:cache = @{ - AzureAdJoined = $false - IntuneEnrolled = $false - EmTaskExists = $false - EnrollmentId = $null - DeviceId = $null - DeviceIdReported = $false + AzureAdJoined = $false + IntuneEnrolled = $false + EmTaskExists = $false + EnrollmentId = $null + DeviceId = $null + DeviceIdReported = $false + LockdownCompletePushed = $false } # Load Send-PxeStatus at SCRIPT scope (not inside a function). A dot-source @@ -235,6 +236,46 @@ function Get-Phase1 { } } + # Lockdown-applied auto-completion. Fleet-wide reality: bays use a LOCAL + # ShopFloor account, so AzureAdPrt stays NO and user-scoped Intune policies + # never deliver. The natural completion gate (baseline policies >= 5, DSC + # Installation completed successfully, all Phase 4 wrappers) therefore + # never closes - leaves the dashboard stuck at 7/8 = 87.5% forever. + # + # Real-world definition of "done" for these bays is lockdown applied: + # Winlogon DefaultUserName flipped to ShopFloor + AutoAdminLogon=1, OR + # the force-lockdown marker has been written by sfld_autologon.ps1. + # When either signal is present, push idx=8 / status=succeeded so the + # dashboard card flips to 100% green. + if (-not $script:cache.LockdownCompletePushed) { + $lockdownApplied = $false + try { + $wl = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -ErrorAction Stop + if ([string]$wl.AutoAdminLogon -eq '1' -and $wl.DefaultUserName -like 'ShopFloor*') { + $lockdownApplied = $true + } + } catch {} + if (-not $lockdownApplied -and (Test-Path 'C:\Enrollment\force-lockdown-applied.txt')) { + $lockdownApplied = $true + } + if ($lockdownApplied) { + Ensure-SendPxeStatus + if (Get-Command Send-PxeStatus -ErrorAction SilentlyContinue) { + try { + $params = @{ + Stage = 'Monitor-IntuneProgress: lockdown applied (imaging complete)' + StageIndex = 8 + StageTotal = 8 + Status = 'succeeded' + } + if ($script:cache.DeviceId) { $params.IntuneDeviceId = $script:cache.DeviceId } + Send-PxeStatus @params + $script:cache.LockdownCompletePushed = $true + } catch { } + } + } + } + if (-not $script:cache.IntuneEnrolled) { $eid = Get-EnrollmentId if ($eid) {