Files
pxe-server/playbook/winpe-status-push.ps1
cproudlock 9d75d03b2d 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.
2026-10-16 10:09:40 -04:00

106 lines
3.9 KiB
PowerShell

# winpe-status-push.ps1 - Posts "WinPE: PESetup / WIM apply" status to the
# PXE webapp /imaging/status endpoint so the imaging dashboard reflects
# this bay BEFORE Run-ShopfloorSetup.ps1 takes over post-PPKG.
#
# Runs in WinPE's stripped PowerShell - cannot rely on Get-NetAdapter,
# Get-CimInstance, or the NetTCPIP module (none are present in stock
# WinPE). Uses wmic for both serial and MAC.
#
# Best-effort: never blocks imaging. All steps log to
# X:\Windows\Temp\winpe-status-push.log; failures are swallowed.
param(
[string]$PxeServer = '172.16.9.1',
[int]$Port = 9009,
[int]$TimeoutSec = 5,
[string]$PCType = $env:PCTYPE,
[string]$CurrentStage = 'WinPE: PESetup / WIM apply',
[int]$StageIndex = 1,
# check-bios.cmd (run before the imaging menu) writes this when it staged
# a firmware update; the flash itself happens at the reboot after WinPE.
[string]$BiosFlag = 'X:\bios-fired.flag'
)
$logFile = 'X:\Windows\Temp\winpe-status-push.log'
function Log {
param([string]$msg)
try { "$(Get-Date -Format s) $msg" | Out-File -FilePath $logFile -Append -Encoding utf8 } catch { }
}
Log "=== winpe-status-push start ==="
Log "server=${PxeServer}:${Port} pctype=$PCType"
# Serial via wmic. Always available in WinPE 10+.
$serial = ''
try {
$line = (& wmic bios get serialnumber /value 2>$null | Where-Object { $_ -match '=' } | Select-Object -First 1)
if ($line) { $serial = ($line -split '=', 2)[1].Trim() }
} catch { Log "serial wmic exception: $_" }
if (-not $serial) {
# wmic is a removable feature on newer Windows; CIM where it exists.
try { $serial = ((Get-CimInstance -ClassName Win32_BIOS -ErrorAction Stop).SerialNumber -as [string]).Trim() } catch { }
}
Log "serial=$serial"
# MAC via wmic NIC enumeration. NetEnabled filter restricts to up adapters.
$mac = ''
try {
$macLines = & wmic nic where 'NetEnabled=TRUE' get MacAddress /value 2>$null |
Where-Object { $_ -match 'MacAddress=' }
if ($macLines) {
$first = ($macLines | Select-Object -First 1)
$mac = (($first -split '=', 2)[1]).Trim() -replace '-', ':'
}
} catch { Log "mac wmic exception: $_" }
Log "mac=$mac"
if (-not $serial) {
Log "no serial captured - aborting POST"
exit 0
}
# gea-standard / gea-engineer set no PCTYPE: read the image from the share
# startnet mapped as Z: (\\server\winpeapps\<image>). Those builds report
# 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 = 3 }
} catch { Log "net use Z: exception: $_" }
Log "image from Z: = '$PCType'"
}
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.
if ($CurrentStage -eq 'WinPE: PESetup / WIM apply' -and (Test-Path $BiosFlag)) {
$CurrentStage = 'WinPE: PESetup / WIM apply (BIOS update staged, flashes on the next reboot)'
Log "bios flag present: $((Get-Content $BiosFlag -ErrorAction SilentlyContinue) -join ' ')"
}
# Compose JSON. ConvertTo-Json works in WinPE.
$payload = @{
serial = $serial
pctype = $PCType
current_stage = $CurrentStage
stage_index = $StageIndex
stage_total = $total
status = 'in_progress'
}
if ($mac) { $payload.mac = $mac }
$body = $payload | ConvertTo-Json -Compress
$uri = "http://${PxeServer}:${Port}/imaging/status"
Log "POST $uri body=$body"
try {
$resp = Invoke-WebRequest -Uri $uri -Method POST -Body $body `
-ContentType 'application/json' -UseBasicParsing -TimeoutSec $TimeoutSec -ErrorAction Stop
Log "OK http=$($resp.StatusCode)"
} catch {
Log "ERR $($_.Exception.Message)"
}
exit 0