Record who owns what, and report repo-vs-share drift
OWNERSHIP.md Every expensive bug in this pipeline has had one shape: two systems setting the same thing, last writer winning silently. Four happened on 2026-08-06 alone - computer name (package vs run-enrollment), drive letters (PESetup vs a volume finder), enrollment (package vs an at-logon -ManualFallback task that syspreped finished machines), kiosk URLs (GE-Enforce vs site-config). Each is written down with the evidence so the next person deletes a writer instead of adding one. share-drift.py The share is production and the repo is meant to describe it, but drift runs both ways: live hand-edits nobody committed, and repo fixes never deployed. The unattend outage lived only on the share while the repo copy was fine, and nothing compared them. Each mapped pair is classified. git-owned means the repo wins and the pair must match - those fail the run. unreconciled means the two have genuinely diverged and nobody has decided; reported, not failed. The unattends are unreconciled on purpose: live is ~17 KB against ~12 KB in the repo, so a blind push would regress production. Reads over SSH via base64 so BOM and CRLF survive the hop. First run: 8 git-owned pairs all match, 4 known-unreconciled. Run-ShopfloorSetup.ps1 Corrects a comment that was actively misleading. It claimed shopfloor PCs are "vanilla by design" and that the orchestrator runs -ManualFallback to skip BPRT injection and the package entirely. Shopfloor bays DO enrol - the SFLD package joins Entra with its BPRT token and a human assigns the device category in Intune. -ManualFallback runs sysprep /oobe /reboot, which is why wiring it to an at-logon task destroyed the deployment chain. The absent Entra wait is still correct, for a different reason: at that point the bay is on the isolated PXE LAN with no route to Entra (579C144 held 172.16.9.81 and 172.24.19.142, neither in the production ranges). sync_intune retries until the tech re-cables. "Entra ID Joined: false" right after imaging is normal.
This commit is contained in:
@@ -62,7 +62,7 @@ cmd /c "shutdown /a 2>nul" *>$null
|
||||
# done work and continues from where it left off.
|
||||
#
|
||||
# Also top up AutoLogonCount so the SupportUser autologon budget
|
||||
# (LogonCount=7 from unattend XML) survives extra unplanned reboots.
|
||||
# (LogonCount=12 from unattend XML) survives extra unplanned reboots.
|
||||
$selfResumeKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce'
|
||||
$selfResumeName = 'ResumeRunShopfloorSetup'
|
||||
$selfResumeCmd = 'powershell.exe -NoProfile -ExecutionPolicy Bypass -File "' + $PSCommandPath + '"'
|
||||
@@ -94,9 +94,51 @@ $enrollDir = "C:\Enrollment"
|
||||
$typeFile = Join-Path $enrollDir "pc-type.txt"
|
||||
$setupDir = Join-Path $enrollDir "shopfloor-setup"
|
||||
|
||||
# NOTE: there is deliberately NO wait for an Entra join here - but NOT because
|
||||
# shopfloor bays skip enrollment. They do enrol: the SFLD provisioning package
|
||||
# joins Entra using the BPRT token it carries, and a human then assigns the
|
||||
# device category in Intune.
|
||||
#
|
||||
# The wait is absent because the join cannot happen yet. At this point the bay is
|
||||
# still on the isolated PXE LAN with no route to Entra - observed on 579C144
|
||||
# 2026-08-06, holding 172.16.9.81 and 172.24.19.142, neither in the production
|
||||
# ranges. sync_intune retries every 30 seconds until the tech re-cables to
|
||||
# production, which is the right place to wait. An earlier version blocked here
|
||||
# for 45 minutes and then warned about a failure that had not happened.
|
||||
# "Entra ID Joined: false" in C:\Logs\BPRT\criticalChecks.json straight after
|
||||
# imaging is therefore NORMAL, not a fault.
|
||||
#
|
||||
# CORRECTION (2026-08-06): this comment previously claimed shopfloor PCs are
|
||||
# "vanilla by design" and that the orchestrator runs with -ManualFallback to skip
|
||||
# BPRT injection and the package entirely. That was wrong and dangerous.
|
||||
# -ManualFallback runs sysprep /oobe /reboot, so wiring it to an at-logon task
|
||||
# syspreped finished machines seconds after autologon and destroyed the
|
||||
# deployment chain. See docs/OWNERSHIP.md.
|
||||
|
||||
if (-not (Test-Path $typeFile)) {
|
||||
Write-Host "No pc-type.txt found - skipping shopfloor setup."
|
||||
exit 0
|
||||
# A missing pc-type.txt means one of two very different things, and the old
|
||||
# blanket "skip + exit 0" hid the bad one for weeks: four Display bays sat
|
||||
# at imaging stage 2 with a green exit code and nobody noticed.
|
||||
# - no C:\Enrollment at all -> this machine was never staged by WinPE
|
||||
# (pre-imaging, or the staging block never ran). That is a FAILURE on a
|
||||
# machine that has clearly just been imaged, so say so loudly.
|
||||
# - C:\Enrollment exists but no pc-type.txt -> staging ran and the write
|
||||
# failed. Also a failure.
|
||||
$stagingLog = Join-Path $enrollDir 'winpe-staging.log'
|
||||
$detail = if (Test-Path $enrollDir) {
|
||||
"C:\Enrollment exists but pc-type.txt is missing - WinPE staging ran but did not write it. Check $stagingLog."
|
||||
} else {
|
||||
"C:\Enrollment does not exist - WinPE staging never ran. The Windows volume was probably not found in startnet.cmd, so pc-type.txt, the enrollment package and shopfloor-setup were ALL skipped."
|
||||
}
|
||||
Write-Host ""
|
||||
Write-Host "================================================================"
|
||||
Write-Host " FAILED: no pc-type.txt at $typeFile"
|
||||
Write-Host " $detail"
|
||||
Write-Host " Shopfloor setup cannot run. This PC is imaged but NOT configured."
|
||||
Write-Host "================================================================"
|
||||
Write-Host ""
|
||||
Report-Stage -Stage 'Run-ShopfloorSetup: FAILED - no pc-type.txt' -Index 2 -Status 'failed' -Error_ $detail
|
||||
exit 1
|
||||
}
|
||||
|
||||
$pcType = (Get-Content $typeFile -First 1).Trim()
|
||||
|
||||
Reference in New Issue
Block a user