From 9d75d03b2d599d1d780b2c0d09882c613b1ac024 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Fri, 16 Oct 2026 10:09:40 -0400 Subject: [PATCH] Standard/Engineer builds are done at OOBE on the imaging floor Everything after OOBE needs the employee to log in, which happens off the PXE network, so the floor waited forever at step 3 of 5. Now 3 steps: WinPE, Windows setup installing apps, ready at OOBE (succeeded). - both unattends: specialize Order 49 posts step 3 as succeeded (Path 182 chars; lint clean). Only that line changed. - Send-ImagingStage.ps1: StageTotal 3; steps above the total (the old first-logon steps 4 and 5 still in the unattends) are logged and not posted, so they cannot reopen a finished build - winpe-status-push.ps1: total 3 for gea-standard / gea-engineer - floor tile step 3: "Ready at OOBE" Tested in the win11 VM against the test server: steps 2 and 3 post, step 3 shows succeeded, step 4 is skipped. Not deployed: the unattends go out only through scripts/deploy-unattend.sh. --- playbook/FlatUnattendW10-engineer.xml | 4 ++-- playbook/FlatUnattendW10.xml | 4 ++-- playbook/imaging-status/Send-ImagingStage.ps1 | 13 ++++++++++++- playbook/winpe-status-push.ps1 | 8 ++++---- webapp/templates/_imaging_tiles.html | 6 ++++-- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/playbook/FlatUnattendW10-engineer.xml b/playbook/FlatUnattendW10-engineer.xml index ae26e91..f66f511 100644 --- a/playbook/FlatUnattendW10-engineer.xml +++ b/playbook/FlatUnattendW10-engineer.xml @@ -311,8 +311,8 @@ 49 - powershell.exe -NoP -EP Bypass -File C:\ProgramData\PxeStatus\Send-ImagingStage.ps1 -PCType gea-engineer -StageIndex 3 -Stage "Apps installed - waiting for first logon" - PXE status: stage 3 of 5 + powershell.exe -NoP -EP Bypass -File C:\ProgramData\PxeStatus\Send-ImagingStage.ps1 -PCType gea-engineer -StageIndex 3 -Status succeeded -Stage "Ready at OOBE - hand to the employee" + PXE status: stage 3 of 3, done (the rest needs the employee to log in) diff --git a/playbook/FlatUnattendW10.xml b/playbook/FlatUnattendW10.xml index cf36f14..4e8f83f 100644 --- a/playbook/FlatUnattendW10.xml +++ b/playbook/FlatUnattendW10.xml @@ -311,8 +311,8 @@ 49 - powershell.exe -NoP -EP Bypass -File C:\ProgramData\PxeStatus\Send-ImagingStage.ps1 -PCType gea-standard -StageIndex 3 -Stage "Apps installed - waiting for first logon" - PXE status: stage 3 of 5 + powershell.exe -NoP -EP Bypass -File C:\ProgramData\PxeStatus\Send-ImagingStage.ps1 -PCType gea-standard -StageIndex 3 -Status succeeded -Stage "Ready at OOBE - hand to the employee" + PXE status: stage 3 of 3, done (the rest needs the employee to log in) diff --git a/playbook/imaging-status/Send-ImagingStage.ps1 b/playbook/imaging-status/Send-ImagingStage.ps1 index d5d135f..d1d65a4 100644 --- a/playbook/imaging-status/Send-ImagingStage.ps1 +++ b/playbook/imaging-status/Send-ImagingStage.ps1 @@ -13,11 +13,17 @@ # Best-effort: never blocks or fails Windows setup. Every error is swallowed, # the script always exits 0, and each attempt is logged to # C:\Logs\send-imaging-stage.log. +# +# Three steps: 1 WinPE, 2 Windows setup installing apps, 3 ready at OOBE +# (succeeded). Everything after OOBE needs the employee to log in, which +# happens off the PXE network, so PXE cannot see it. Steps above +# StageTotal (the old first-logon steps 4 and 5 still in the unattends) are +# logged and not posted, so they cannot reopen a finished build. param( [Parameter(Mandatory = $true)][string]$Stage, [int]$StageIndex = 0, - [int]$StageTotal = 5, + [int]$StageTotal = 3, [string]$PCType = '', [ValidateSet('in_progress', 'succeeded', 'failed')][string]$Status = 'in_progress', [string]$PxeServer = '172.16.9.1', @@ -43,6 +49,11 @@ if ($Persist) { } catch { Log "persist failed: $($_.Exception.Message)" } } +if ($StageIndex -gt $StageTotal) { + Log "SKIP stage $StageIndex of $StageTotal (after OOBE; PXE does not track it): $Stage" + exit 0 +} + try { $serial = $null try { $serial = (Get-CimInstance -ClassName Win32_BIOS -ErrorAction Stop).SerialNumber } catch { diff --git a/playbook/winpe-status-push.ps1 b/playbook/winpe-status-push.ps1 index d00904e..81b07d1 100644 --- a/playbook/winpe-status-push.ps1 +++ b/playbook/winpe-status-push.ps1 @@ -61,17 +61,17 @@ if (-not $serial) { # gea-standard / gea-engineer set no PCTYPE: read the image from the share # startnet mapped as Z: (\\server\winpeapps\). Those builds report -# 5 steps (WinPE, then Send-ImagingStage.ps1 from their unattend); the -# shopfloor build reports 8. +# 3 steps (WinPE, then Send-ImagingStage.ps1 from their unattend, done +# at OOBE); the shopfloor build reports 8. $total = 8 if (-not $PCType) { try { $z = (& net use Z: 2>$null | Out-String) - if ($z -match 'winpeapps\\(gea-standard|gea-engineer)\b') { $PCType = $Matches[1]; $total = 5 } + if ($z -match 'winpeapps\\(gea-standard|gea-engineer)\b') { $PCType = $Matches[1]; $total = 3 } } catch { Log "net use Z: exception: $_" } Log "image from Z: = '$PCType'" } -if ($PCType -in @('gea-standard', 'gea-engineer')) { $total = 5 } +if ($PCType -in @('gea-standard', 'gea-engineer')) { $total = 3 } # Say so from the first push: the BIOS update was staged before the menu, but # startnet's own "BIOS firmware update" push only comes at the end of WinPE. diff --git a/webapp/templates/_imaging_tiles.html b/webapp/templates/_imaging_tiles.html index 6f8d5c4..8c209ef 100644 --- a/webapp/templates/_imaging_tiles.html +++ b/webapp/templates/_imaging_tiles.html @@ -18,11 +18,13 @@ } %} {# gea-standard / gea-engineer builds: WinPE push, then - Send-ImagingStage.ps1 from the image's unattend; stage_total 5. #} + Send-ImagingStage.ps1 from the image's unattend; stage_total 3. Done + at OOBE: everything after needs the employee's logon, off the PXE + network. (4 and 5 are kept for builds still running the old unattend.) #} {% set desk_stage_labels = { 1: ('Applying Windows image', 'WinPE loaded - PESetup is applying the Windows image to disk.'), 2: ('Windows setup: installing apps','First boot (specialize): certificates, WiFi, fonts, Adobe, Java and the enrollment task.'), - 3: ('Waiting for first logon', 'Apps installed. Windows setup finishes when someone logs on to the PC.'), + 3: ('Ready at OOBE', 'PXE imaging is done. Hand the PC to the employee: first logon (and the engineering layer on Engineer builds) runs when they sign in.'), 4: ('First logon', 'First logon commands running (the engineering layer on Engineer builds).'), 5: ('Setup complete', 'Imaging is done; bulk enrollment continues on the PC.') } %}