@@ -864,13 +864,6 @@ function Install-StandardApps {
864864 -2147012889 # 0x80072EE7 InternetOpenUrl failed / WinHTTP unknown error
865865 )
866866
867- # Known permanent failure codes — not retried, shown with a friendly message
868- $knownFailMessages = @ {
869- ' -1978335215' = ' Installer hash mismatch (try again later or check proxy/AV)' # 0x8A150011
870- ' -1978335212' = ' Package not found in winget source (ID may have changed)' # 0x8A15002C
871- ' -1978334960' = ' Installer blocked by security policy' # 0x8A150110
872- ' -1978335132' = ' Installer requires reboot before proceeding' # 0x8A150064
873- }
874867 $maxRetries = 2
875868 $retryDelaySec = 10
876869
@@ -938,21 +931,30 @@ function Install-StandardApps {
938931 Add-Result - Section (T ' PhaseApps' ) - Item $app.Name - Status ' OK' - Detail (T ' AlreadyInstalled' )
939932 $script :Summary.AppsInstalled ++
940933 } else {
941- # Resolve a friendly reason — use known message or fall back to exit code
942- $failReason = if ($knownFailMessages.ContainsKey (" $exitCode " )) {
943- $knownFailMessages [" $exitCode " ]
944- } else {
945- " Exit code $exitCode "
934+ # Map exit code to a human-readable reason.
935+ # Using switch($int) avoids hashtable string/int key-type ambiguity.
936+ # Network codes here cover the "all retries exhausted" path.
937+ $failReason = switch ($exitCode ) {
938+ -1978335215 { ' Installer hash mismatch — retry later or check proxy/AV' } # 0x8A150011
939+ -1978335212 { ' Package not found in winget source (ID may have changed)' } # 0x8A15002C
940+ -1978334960 { ' Installer blocked by security policy' } # 0x8A150110
941+ -1978335132 { ' Installer requires reboot before continuing' } # 0x8A150064
942+ -1978334967 { ' Network failure — download failed (all retries exhausted)' } # 0x8A150109
943+ -1978334966 { ' Network failure — timed out (all retries exhausted)' } # 0x8A15010A
944+ -2147012887 { ' Network failure — connection reset (all retries exhausted)' } # 0x80072EE9
945+ -2147012873 { ' Network failure — DNS not resolved (all retries exhausted)' } # 0x80072EF7
946+ -2147012867 { ' Network failure — connection refused (all retries exhausted)' } # 0x80072EFD
947+ -2147012889 { ' Network failure — WinHTTP error (all retries exhausted)' } # 0x80072EE7
948+ default { " Exit code $exitCode " }
946949 }
947950 Write-Log " $ ( T ' InstallFail' ) : $ ( $app.Name ) - $failReason " - Level ' WARN'
948951 # Log last clean lines of winget output — strip progress-bar/spinner noise
949952 $diagLines = ($wingetOut | Where-Object { " $_ " .Trim() }) | Select-Object - Last 8
950953 foreach ($line in $diagLines ) {
951- # Strip non-printable chars, then skip spinner frames and short noise
952- $clean = (" $line " -replace ' [^\x20-\x7E]' , ' ' ).Trim()
953- if ($clean.Length -lt 8 ) { continue } # too short (spinner: \|/-)
954- if ($clean -match ' ^[\\|/\-]+$' ) { continue } # pure spinner frame
955- if ($clean -match ' ^\s*\d+\s*MB' ) { continue } # progress bytes only
954+ $clean = (" $line " -replace ' [^ -~]' , ' ' ).Trim()
955+ if ($clean.Length -lt 8 ) { continue } # spinner chars: \|/-
956+ if ($clean -match ' ^[\|/\-]+$' ) { continue } # pure spinner frame
957+ if ($clean -match ' ^\s*\d+\s*MB' ) { continue } # "141 MB / 143 MB" lines
956958 Write-Log " $clean " - Level ' WARN'
957959 }
958960 Add-Result - Section (T ' PhaseApps' ) - Item $app.Name - Status ' WARN' - Detail $failReason
0 commit comments