# 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\). 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