heal/fetch: suppress benign net-use-delete error during imaging

The pre-mount `net use Z: /delete /y` in Fetch-StagingPayload and
Verify-And-Heal-Staging emits "The network connection could not be found" when
Z: is not yet mapped (the normal first-attempt case). PowerShell surfaces that
native stderr as a NativeCommandError (System.Management.Automation.Remote-
Exception) at the call site EVEN WITH `2>$null` - it prints a red error during
the FirstLogonCommands run, alarming the tech and able to mask a real fault.
The mount then succeeds, so it was always cosmetic.

Wrap the cleanup in cmd.exe (`cmd /c "net use $drive /delete /y >/dev/null 2>&1"`) so
net.exe's stderr is redirected to nul INSIDE cmd and never reaches PowerShell as
an error record. Verified on the win11 VM: old pattern leaves $Error.Count=4
(RemoteException); new pattern leaves $Error.Count=0. All four call sites fixed
(both scripts' Mount-Share + end-of-run unmount).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
cproudlock
2026-06-14 11:50:27 -04:00
parent 51edf98e7d
commit 9145023440
2 changed files with 8 additions and 4 deletions

View File

@@ -86,7 +86,11 @@ if (Test-Path $pxeStatusLib) { try { . $pxeStatusLib; Send-PxeStatus -Stage 'Fet
# --- Mount the share fresh (use Z:; retry to ride out a brief blip) --- # --- Mount the share fresh (use Z:; retry to ride out a brief blip) ---
$drive = 'Z:' $drive = 'Z:'
function Mount-Share { function Mount-Share {
& net use $drive /delete /y 2>$null | Out-Null # Pre-clear any stale Z: mapping. Wrap in cmd.exe (output to nul INSIDE cmd)
# so net.exe's "network connection could not be found" stderr - emitted when
# Z: is not mapped (the normal first-attempt case) - never reaches PowerShell
# as a NativeCommandError. PS 2>$null does not reliably suppress that.
cmd /c "net use $drive /delete /y >nul 2>&1"
$r = & net use $drive $shareUnc /user:$shareUser $sharePass /persistent:no 2>&1 $r = & net use $drive $shareUnc /user:$shareUser $sharePass /persistent:no 2>&1
return ($LASTEXITCODE -eq 0) return ($LASTEXITCODE -eq 0)
} }
@@ -160,7 +164,7 @@ Fetch-Item -Label 'preinstall installers' -SrcDir 'pre-install\installers' -DstD
Fetch-Item -Label 'udc-backups' -SrcDir 'pre-install\udc-backups' -DstDir (Join-Path $PIN 'udc-backups') -Recurse Fetch-Item -Label 'udc-backups' -SrcDir 'pre-install\udc-backups' -DstDir (Join-Path $PIN 'udc-backups') -Recurse
# --- Unmount --- # --- Unmount ---
& net use $drive /delete /y 2>$null | Out-Null cmd /c "net use $drive /delete /y >nul 2>&1"
# --- Summary table --- # --- Summary table ---
Log "================================================================" Log "================================================================"

View File

@@ -99,7 +99,7 @@ if ($pcType -eq 'gea-shopfloor-cmm') {
# non-empty. VerifyOnly adds /L (list-only): it reports what WOULD be re-pulled # non-empty. VerifyOnly adds /L (list-only): it reports what WOULD be re-pulled
# without changing anything. # without changing anything.
$drive='Z:'; $mounted=$false $drive='Z:'; $mounted=$false
function Mount-Share { & net use $drive /delete /y 2>$null | Out-Null; & net use $drive $ShareUnc /user:$ShareUser $SharePass /persistent:no 2>&1 | Out-Null; return ($LASTEXITCODE -eq 0) } function Mount-Share { cmd /c "net use $drive /delete /y >nul 2>&1"; & net use $drive $ShareUnc /user:$ShareUser $SharePass /persistent:no 2>&1 | Out-Null; return ($LASTEXITCODE -eq 0) }
$report = New-Object System.Collections.Generic.List[object] $report = New-Object System.Collections.Generic.List[object]
for ($a=1; $a -le 5 -and -not $mounted; $a++){ if (Mount-Share){$mounted=$true;Log "Mounted $ShareUnc as $drive"} else {Log "mount attempt $a/5 failed - 10s" 'WARN'; Start-Sleep 10} } for ($a=1; $a -le 5 -and -not $mounted; $a++){ if (Mount-Share){$mounted=$true;Log "Mounted $ShareUnc as $drive"} else {Log "mount attempt $a/5 failed - 10s" 'WARN'; Start-Sleep 10} }
@@ -132,7 +132,7 @@ if (-not $mounted) {
$report.Add([pscustomobject]@{Item=$it.Label;Status=$status}) $report.Add([pscustomobject]@{Item=$it.Label;Status=$status})
Log "[$($it.Label)] robocopy rc=$rc -> $status $(("$files").Trim())" Log "[$($it.Label)] robocopy rc=$rc -> $status $(("$files").Trim())"
} }
& net use $drive /delete /y 2>$null | Out-Null cmd /c "net use $drive /delete /y >nul 2>&1"
} }
# --- report -------------------------------------------------------------------- # --- report --------------------------------------------------------------------