Review on #132013 (Enough1122): $ProgressPreference and the CLIXML strip
only covered probeWindowsRemote, but the same SSH connection runs four
more PowerShell builders that parse stdout the same way.
- windowsUpdateMarkerProbeCommand: fail-closed gate in
assertWindowsRemoteInstallUpdateClear reads .pop() of the last line —
a progress record serialized after the final Write-Output used to win
the pop and refuse SSH startup as kind='update-in-progress' (misleading
safety verdict). Add-Type compiles C# in this script, well outside the
probe's Get-Item/Get-Command progress suppression.
- helperCommand / atomicWindowsSpawnCommand: import the remote
hermes_cli module (auto-load progress) and JSON-parse the last line.
Extract stripPowerShellNoise (BOM strip + CLIXML block removal + the
last-meaningful-line convention) and share it across all four parsers;
prepend $ProgressPreference to the three parsed builders. The fourth
builder, buildWindowsInteractiveCommand, drives a -tt pty the user reads
directly — nothing parses its output, so it keeps no strip.
On the stderr premise: the issue's error string is the _fail() default
('SSH error connecting to …'), i.e. CLIXML in stderr on a non-zero exit —
exec() throws before any parse in that case, so the stdout strip is
defense-in-depth for the stdout-channel race the issue's grep loop
shows; $ProgressPreference suppresses both channels at the source.
Tests: the marker gate stays CLEAR with CLIXML before/after the verdict
line (red on base via .pop()), LIVE still pauses startup; all three
parsed builders pin $ProgressPreference before $ErrorActionPreference;
helper tolerates CLIXML around its JSON.