Search code examples
powershellwinget

How to i get rid of the extra stuff at the to?


Hi I've been writing a PowerShell script that uses the Winget CLI tool but whenever I'm trying to use it in the way below this is the output that I keep getting when really what I want is the output that Powershell or CMD will give me if I just put it in normally


My Script

$AppsToUpdate1 = Start-Job { winget upgrade }
$AppsToUpdate2 = Wait-Job $AppsToUpdate1 | Out-Null; Receive-Job $AppsToUpdate1

Write-Output $AppsToUpdate2```

The output


   -
   \
   |
   /
   /
   /
   /
   -
   \
   |


   -

No installed package found matching input criteria.

The following packages have an upgrade available, but require explicit targeting for upgrade:
Name    Id              Version  Available Source
-------------------------------------------------
Discord Discord.Discord 1.0.9003 1.0.9156  winget

The output i want/CMD and PS will give

No installed package found matching input criteria.

The following packages have an upgrade available, but require explicit targeting for upgrade:
Name    Id              Version  Available Source
-------------------------------------------------
Discord Discord.Discord 1.0.9003 1.0.9156  winget

Solution

    • What you're seeing is an artifact of the progress display that winget.exe emits.

    • Unfortunately, as of v1.8.1911 of winget.exe, there appears to be no way to prevent these artifacts when you capture the output, as invariably happens when you use Start-Job, for instance: neither --silent (-h) nor --disable-interactivity help, as these options appear to relate to interactive prompting only.

      • Arguably, winget.exe itself should detect when its output is being captured - as opposed to printing to the display (console aka. terminal) - and then not show progress information.

    Solution options:

    • Either: Filter out the progress information from the captured output after the fact, as follows:

      winget upgrade | Where-Object { $_ -notmatch '^\s+[-/\|\s]+$|^$' }
      
    • Or: Use the Microsoft.WinGet.Client module instead, which is generally preferable, as it enables robust, object-based processing, without any progress display (there is currently none) getting in the way:

      • Install it as follows, for example:

         Install-Module -Scope CurrentUser Microsoft.WinGet.Client
        
      • Then use the following command:

         Get-WinGetPackage | Where-Object IsUpdateAvailable
        
      • Caveat:

        • The above is not the exact equivalent of winget upgrade in that it (a) invariably implies --include-unknown and (b) lacks support for --include-pinned - see GitHub issue #4375 for details.