Files
pxe-server/playbook/shopfloor-setup/BPRT/Select-PCConfig.ps1
cproudlock 9d51c0b987 Ask tenant + PC purpose at the PXE menu; add the missing 3D kiosk display option
PC PURPOSE / TENANT FOR STANDARD AND ENGINEER

The capability was already there - the media carries all six MCL packages
(PERS/SH/LOAN x GCCH/RoW) and Start-BulkEnrollOrchestrator.ps1 picks one from
whatever Select-PCConfig.ps1 returns. The problem was WHEN it asks: a GUI at
first logon, so an otherwise unattended build stops at a dialog until someone
walks over.

Now startnet asks after Standard/Engineer is chosen, while the tech who knows
what the machine is for is standing at it, and writes {Tenant}_{Purpose} to
C:\Enrollment\pc-config.txt. A shim at the path the orchestrator already calls
returns that value and falls through to the vendor dialog when it is absent or
malformed - so "ask at first logon" stays available and bays imaged before this
are unaffected. The vendor script is preserved as Select-PCConfig-vendor.ps1;
replace THAT when the vendor ships a new one.

The tenant is not cosmetic. Insert-BPRTToPPKG.ps1 matches the bulk token on
Tenant AND Purpose, so this selects which token gets injected.

ONLY THE CHOICE IS PRE-SEEDED, deliberately. Injection stays at first logon
because it fetches an encrypted token table from mcl.dwcdn.geaerospace.com,
unreachable from the isolated imaging LAN - which is also why routing MCL
packages through run-enrollment.ps1 would not work: provtool would get a package
whose token is still the Exp_XXXXXXXX placeholder and join nothing.

Standard/engineer previously skipped staging entirely (no ppkg, no PCTYPE), so
the staging gate now also admits PCCONFIG.

3D PARTS KIOSK

The display submenu offered Dashboard and Lobby only. The GE-Enforce display
scope has always had a third entry - 3DPrintRoom -> /shopdb/parts-kiosk - so a
parts kiosk could only be set by editing display-type.txt by hand after imaging.
Added as option 3. The value is a KEY into that map, so the spelling matches
exactly.

Verified: startnet parens balance, every goto resolves, 994 CRLF lines with no
bare LF; shim parses clean. Deployed - boot.wim 4d16c946, shim staged with the
vendor dialog preserved.
2026-08-06 14:37:20 -04:00

85 lines
3.2 KiB
PowerShell

<#
.SYNOPSIS
Return the tenant + PC purpose, pre-seeded if WinPE already asked.
.DESCRIPTION
Start-BulkEnrollOrchestrator.ps1 calls this at first logon and captures
stdout:
$pcType = powershell.exe -File 'C:\Deploy\Applications\BPRT\Select-PCConfig.ps1' -LogoPath '...'
It uses the answer twice - to pick which MCL package to apply, and to select
which bulk token Insert-BPRTToPPKG.ps1 injects (it matches on Tenant AND
Purpose). The vendor's version asks with a GUI, which means an otherwise
unattended build stops at a dialog until somebody walks over.
startnet.cmd now asks the same question at the PXE menu, while the tech who
knows what the machine is for is standing at it, and writes the answer to
C:\Enrollment\pc-config.txt. This shim returns that value when present and
falls through to the vendor dialog when it is not - so nothing is lost if the
tech picks "ask at first logon", or on a bay imaged before this existed.
ONLY the choice is pre-seeded. Token injection still happens at first logon:
Insert-BPRTToPPKG.ps1 fetches an encrypted token table from
mcl.dwcdn.geaerospace.com, which is unreachable from the isolated imaging
LAN.
.OUTPUTS
"{Tenant}_{PCType}" - Tenant GCCH|RoW, PCType PERS|SH|LOAN.
Identical contract to the vendor script.
.NOTES
The vendor script is kept alongside as Select-PCConfig-vendor.ps1. Replace
THAT file when the vendor ships a new one; this shim only needs changing if
the return contract changes.
#>
param(
[Parameter(Mandatory = $false)]
[string]$LogoPath
)
$seedFile = 'C:\Enrollment\pc-config.txt'
$vendor = Join-Path $PSScriptRoot 'Select-PCConfig-vendor.ps1'
$logDir = 'C:\Logs\BPRT\Orchestrator'
$shimLog = Join-Path $logDir 'Select-PCConfig-shim.log'
function Log {
param([string]$Message)
try {
New-Item -ItemType Directory -Path $logDir -Force -ErrorAction SilentlyContinue | Out-Null
Add-Content -Path $shimLog -Value ("{0} {1}" -f (Get-Date -Format 'yyyy-MM-dd HH:mm:ss'), $Message)
} catch { }
}
# Valid values, so a typo in the seed file falls back to the dialog instead of
# handing the orchestrator a string that matches no token and no package.
$validTenants = @('GCCH', 'RoW')
$validPurposes = @('PERS', 'SH', 'LOAN')
if (Test-Path $seedFile) {
$seed = (Get-Content $seedFile -First 1 -ErrorAction SilentlyContinue)
if ($seed) { $seed = $seed.Trim() }
$parts = if ($seed) { $seed.Split('_') } else { @() }
if ($parts.Count -eq 2 -and $validTenants -contains $parts[0] -and $validPurposes -contains $parts[1]) {
Log "Pre-seeded value '$seed' from $seedFile - dialog skipped."
Write-Output $seed
exit 0
}
Log "Ignoring malformed pre-seed '$seed' in $seedFile; falling back to the dialog."
}
if (Test-Path $vendor) {
Log "No usable pre-seed; showing the vendor dialog."
if ($LogoPath) { & $vendor -LogoPath $LogoPath }
else { & $vendor }
exit $LASTEXITCODE
}
# Neither a seed nor the vendor dialog. Say so in the log rather than returning
# something invented - the orchestrator would inject the wrong token.
Log "ERROR: no pre-seed at $seedFile and no vendor script at $vendor."
exit 1