From 3cb939825531f0e071e28e46725b398660ac0eb7 Mon Sep 17 00:00:00 2001 From: hafometh88 <76481827+hafometh88@users.noreply.github.com> Date: Thu, 23 Apr 2026 09:11:13 +0200 Subject: [PATCH 1/2] fix(detection): fix winget output parsing to handle spinner lines and count summaries Anchor header and data row extraction on the separator line ('^-{10,}') instead of assuming the first alpha line is the header and the last line is the data row. Recent winget versions (1.7+) prepend progress spinner lines to stdout, and some versions append a "N package(s)" count summary. Both caused the parser to pick the wrong rows, resulting in exit 10 even when the package was installed. Also guard Substring() against out-of-bounds access when the data row is shorter than the last header column position (e.g. when Available and Source fields are blank and trailing whitespace is trimmed). --- src/WingetIntune/Scripts/WingetDetection.ps1 | 34 +++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/WingetIntune/Scripts/WingetDetection.ps1 b/src/WingetIntune/Scripts/WingetDetection.ps1 index 736af93..a967c23 100644 --- a/src/WingetIntune/Scripts/WingetDetection.ps1 +++ b/src/WingetIntune/Scripts/WingetDetection.ps1 @@ -46,11 +46,25 @@ Function Get-ColumnValuesFromWingetOutput { } if ($Output -is [array] -and $Output.Length -gt 2) { - # $Output is an array, first row is header, last row is data - # this will break if multiple lines are returned, but that should not happen with --exact - #$headerRow = $Output[$Output.Length - 3] - $headerRow = $Output | Where-Object { $_ -match '^[A-Za-z]' } | Select-Object -First 1 - $lastRow = $Output[$Output.Length - 1] + # Anchor on the separator line (--- dashes) which is stable across winget versions. + # Newer winget appends a "N package(s)" count line, so we cannot rely on $Output[-1]. + # Source-refresh messages ("Updating sources...") appear before the table, so we + # cannot rely on the first alpha line being the header. + $separatorIndex = -1 + for ($s = 0; $s -lt $Output.Length; $s++) { + if ($Output[$s] -match '^-{10,}') { + $separatorIndex = $s + break + } + } + + if ($separatorIndex -le 0 -or $separatorIndex + 1 -ge $Output.Length) { + Write-Host "Could not find separator line in winget output" + return @() + } + + $headerRow = $Output[$separatorIndex - 1] + $lastRow = $Output[$separatorIndex + 1] # Find the start index of each column by searching for non-space transitions $columnStarts = @() @@ -63,12 +77,16 @@ Function Get-ColumnValuesFromWingetOutput { # Add the end of the line as the last column boundary $columnStarts += $lastRow.Length - # Extract column values from the data row + # Extract column values from the data row, guarding against short rows $columns = @() for ($i = 0; $i -lt $columnStarts.Count - 1; $i++) { $start = $columnStarts[$i] - $length = $columnStarts[$i + 1] - $start - $columns += $lastRow.Substring($start, $length).Trim() + if ($start -ge $lastRow.Length) { + $columns += "" + } else { + $length = [Math]::Min($columnStarts[$i + 1] - $start, $lastRow.Length - $start) + $columns += $lastRow.Substring($start, $length).Trim() + } } return $columns From b86b0bf881a1aa71f33fb679382764f20720ea5e Mon Sep 17 00:00:00 2001 From: hafometh88 <76481827+hafometh88@users.noreply.github.com> Date: Sat, 13 Jun 2026 00:23:03 +0200 Subject: [PATCH 2/2] trigger CI