shopfloor: stop manifest entries hijacking GE-Enforce's drive letter

GE-Enforce mounts the SFLD share on W: and holds it for the whole enforce
cycle, passing W:\<pctype> as -InstallerRoot to Install-FromManifest. Two
scripts that run inside that cycle, as SYSTEM in the same drive namespace,
mapped W: for their own use and deleted it on exit:

  Restore-UDCData.ps1     manifest PS1 entry, mounts the UDC backup share
  Update-MachineNumber.ps1  "Apply Machine Number" task, same backup share

Once W: is gone, the next manifest entry's Join-Path resolves against a dead
drive qualifier. In Windows PowerShell 5.1 that emits nothing rather than
throwing, so the null lands in Test-Path -LiteralPath and the entry dies with
"Cannot bind argument to parameter 'LiteralPath' because it is null".

Observed on a collections bay: the controller-credential entry, which runs
immediately after UDC Data Restore, failed this way while the entry one line
earlier had resolved a W: path successfully one second before.

Restore-UDCData now uses R: and Update-MachineNumber uses N: for the UDC
backup share. Neither letter is referenced anywhere else in the tree; V: was
not an option because Restore-EDncReg and Update-MachineNumber's NTLARS
restore already use it.

The re-mount at GE-Enforce.ps1:239-244 does not cover this. It runs after the
manifest loop and blames idle SMB timeout, but the whole cycle took one
second, so timeout was never the cause.
This commit is contained in:
cproudlock
2026-08-03 17:22:50 -04:00
parent 1a175bc4fe
commit 66c24b5d59
2 changed files with 22 additions and 12 deletions

View File

@@ -163,10 +163,13 @@ function Update-MachineNumber {
}
if ($udcSharePath) {
try {
$mountedUdc = Mount-SFLDShare -SharePath $udcSharePath -DriveLetter 'W:'
# N:, never W:. GE-Enforce owns W: for its whole cycle, and this
# runs as SYSTEM in the same drive namespace - taking W: here kills
# the share out from under an in-flight enforce cycle.
$mountedUdc = Mount-SFLDShare -SharePath $udcSharePath -DriveLetter 'N:'
if ($mountedUdc) {
try {
$bayDir = Join-Path 'W:\' $NewNumber
$bayDir = Join-Path 'N:\' $NewNumber
$srcCur = Join-Path $bayDir 'CurrentData.json'
$srcArc = Join-Path $bayDir 'ArchivedData'
if (Test-Path -LiteralPath $srcCur) {
@@ -226,7 +229,7 @@ function Update-MachineNumber {
Write-Host " Update-MachineNumber: no UDC backup at $bayDir (fresh PC, no prior data)"
}
} finally {
& net use W: /delete /y 2>$null | Out-Null
& net use N: /delete /y 2>$null | Out-Null
}
} else {
Write-Host " Update-MachineNumber: UDC backup share unreachable - skipping UDC restore."