From c8ef05b86927c2fd8b99d3922840f5382044e311 Mon Sep 17 00:00:00 2001 From: cproudlock Date: Mon, 4 May 2026 19:02:16 -0400 Subject: [PATCH] GE-Enforce: re-mount W: before status write + null guards Root cause of fleet not reporting: long-running entries (UDC's WaitTimeoutSec=120) keep the dispatcher CPU-busy with no SMB traffic to W:. SMB server times out the idle session. W: stays as a "mapped" drive letter on the client but Path operations against it fail with weird errors (e.g. "Cannot bind argument to parameter 'Path' because it is null" via downstream Join-Path / Test-Path null cascades). Fix: - Re-attach W: at the top of the status write-back block (cheap; if still alive net use returns 'already mapped'; if dead, freshly remounts). - Null-guard $hostname (fall back to 'UNKNOWN') and explicitly throw if $driveLetter is unset (catch surfaces a clear error in log). - Pair with UDC manifest WaitTimeoutSec reduction 120 -> 60 on the v2 share to limit how long the SMB stays idle in the first place. Surfaced via blah*.txt log captures from 3 deployed bays (3105, 3115, 3116, 3118 era) - all showed "Status write-back failed: Cannot bind argument to parameter 'Path' because it is null" while everything upstream (manifest entries) ran clean. Co-Authored-By: Claude Opus 4.7 (1M context) --- playbook/shopfloor-setup/common/GE-Enforce.ps1 | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/playbook/shopfloor-setup/common/GE-Enforce.ps1 b/playbook/shopfloor-setup/common/GE-Enforce.ps1 index 36b0f2c..cfbad6f 100644 --- a/playbook/shopfloor-setup/common/GE-Enforce.ps1 +++ b/playbook/shopfloor-setup/common/GE-Enforce.ps1 @@ -236,10 +236,19 @@ try { # continues if the share path is not writable. # ------------------------------------------------------------------ try { + # Re-mount W: before status write-back. Long-running entries (UDC + # WaitTimeoutSec=120) can let the SMB session time out idle, leaving + # W: as a dead drive letter that fails downstream Path operations + # with confusing "argument is null" errors. Cheap to re-attach. + & net use $driveLetter /delete /y 2>$null | Out-Null + & net use $driveLetter $shopfloorShareRoot /user:$($cred.Username) $($cred.Password) /persistent:no 2>&1 | Out-Null + # Live NetBIOS name from kernel - not $env:COMPUTERNAME, which is # cached in the process env block and goes stale after a post-image # rename on Intune-managed PCs. $hostname = [System.Environment]::MachineName + if (-not $hostname) { $hostname = 'UNKNOWN' } + if (-not $driveLetter) { throw 'driveLetter unset before status write-back' } $statusDir = Join-Path (Join-Path $driveLetter '_outputs') (Join-Path 'logs' $hostname) if (-not (Test-Path $statusDir)) { New-Item -Path $statusDir -ItemType Directory -Force -ErrorAction Stop | Out-Null