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.
97 lines
3.9 KiB
PowerShell
97 lines
3.9 KiB
PowerShell
# Send-ImagingStage.ps1 - posts one progress step of a gea-standard /
|
|
# gea-engineer build to the PXE webapp's /imaging/status endpoint, so the
|
|
# imaging floor follows these builds past WinPE (the shopfloor build has its
|
|
# own reporting in Shopfloor\lib\Send-PxeStatus.ps1).
|
|
#
|
|
# Called from the image's FlatUnattendW10.xml (specialize RunSynchronous and
|
|
# oobeSystem FirstLogonCommands). Keep those command lines short: Windows
|
|
# rejects the whole unattend if a RunSynchronous Path exceeds 259 characters
|
|
# (check with scripts/lint-unattend.py --local). Deployed to
|
|
# _shared\Applications\extra\pxe-status\ on the PXE server, which PESetup
|
|
# copies to C:\Deploy\Applications\extra\pxe-status\.
|
|
#
|
|
# 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 = 3,
|
|
[string]$PCType = '',
|
|
[ValidateSet('in_progress', 'succeeded', 'failed')][string]$Status = 'in_progress',
|
|
[string]$PxeServer = '172.16.9.1',
|
|
[int]$Port = 9009,
|
|
[int]$TimeoutSec = 5,
|
|
# Copy this script to C:\ProgramData\PxeStatus first: the bulk-enrollment
|
|
# task deletes C:\Deploy before first logon, when the later steps run.
|
|
[switch]$Persist
|
|
)
|
|
|
|
$logFile = 'C:\Logs\send-imaging-stage.log'
|
|
function Log([string]$msg) {
|
|
try {
|
|
if (-not (Test-Path 'C:\Logs')) { New-Item -ItemType Directory -Path 'C:\Logs' -Force | Out-Null }
|
|
"$(Get-Date -Format s) $msg" | Out-File -FilePath $logFile -Append -Encoding utf8
|
|
} catch { }
|
|
}
|
|
|
|
if ($Persist) {
|
|
try {
|
|
New-Item -ItemType Directory -Path 'C:\ProgramData\PxeStatus' -Force | Out-Null
|
|
Copy-Item -LiteralPath $PSCommandPath -Destination 'C:\ProgramData\PxeStatus\Send-ImagingStage.ps1' -Force
|
|
} 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 {
|
|
try { $serial = (Get-WmiObject -Class Win32_BIOS -ErrorAction Stop).SerialNumber } catch { }
|
|
}
|
|
if ([string]::IsNullOrWhiteSpace($serial)) { $serial = $env:COMPUTERNAME }
|
|
$serial = ($serial -as [string]).Trim()
|
|
|
|
$mac = $null
|
|
try {
|
|
$nic = Get-NetAdapter -Physical -ErrorAction Stop |
|
|
Where-Object { $_.Status -eq 'Up' -and $_.MediaType -eq '802.3' } | Select-Object -First 1
|
|
if ($nic) { $mac = $nic.MacAddress -replace '-', ':' }
|
|
} catch { }
|
|
|
|
$payload = @{
|
|
serial = $serial
|
|
hostname_target = $env:COMPUTERNAME
|
|
current_stage = $Stage
|
|
stage_index = $StageIndex
|
|
stage_total = $StageTotal
|
|
status = $Status
|
|
}
|
|
if ($PCType) { $payload.pctype = $PCType }
|
|
if ($mac) { $payload.mac = $mac }
|
|
$body = $payload | ConvertTo-Json -Compress
|
|
$uri = "http://${PxeServer}:${Port}/imaging/status"
|
|
|
|
try {
|
|
$resp = Invoke-WebRequest -Uri $uri -Method POST -Body $body -ContentType 'application/json' `
|
|
-UseBasicParsing -TimeoutSec $TimeoutSec -ErrorAction Stop
|
|
Log "OK $($resp.StatusCode) $body"
|
|
} catch {
|
|
# Off the imaging network (or the server is down): nothing to report to.
|
|
Log "FAIL $($_.Exception.Message) $body"
|
|
}
|
|
} catch {
|
|
Log "ERROR $($_.Exception.Message)"
|
|
}
|
|
exit 0
|