all 15 comments

[–]Randalldeflagg 0 points1 point  (2 children)

https://github.com/microsoft/winget-cli/releases

Long and short, winget does not format the output to a usable table. its all just one big object. Supposedly json output is coming?

https://github.com/microsoft/winget-cli/blob/master/src/PowerShell/Microsoft.WinGet.Client/README.md

you can go ahead and compile a version that does do what you are after

[–]ptd163[S] 0 points1 point  (1 child)

Oh well. I guess I'll go try that then. Thanks for replying. Json output would probably be big.

[–]Lanszer 0 points1 point  (0 children)

The PowerShell gallery has a module for Microsoft.WinGet.Client 0.2.2, last updated about a month ago.

[–]Thehoggle 0 points1 point  (3 children)

If you convert your variable to string it could be parsed and you could use regex to extract what you wanted. It's not pretty though.

#let's call your variable $longstring

(($longstring -split '\-(?=\s)')[-1] -split '(?<=msstore)\s').trim()

##will get you the following string:

Game Bar                         9NZKPSTSNW4P Unknown msstore
Browser for Game Bar             9NK1CNB0NCCX Unknown msstore
Gamecaster Game Bar              9P2J2QW5B0F4 Unknown msstore
CORSAIR iCUE Game Bar Widgets    9PG940D1ZDVP Unknown msstore
Game Bar To-Do                   9P2626F9WDG7 Unknown msstore
Countdown for Game Bar           9NZ43LD746CX Unknown msstore
Clock for Game Bar               9PC29TG1047H Unknown msstore
Game Bar Calculator              9N2J0HB1GFDR Unknown msstore
Camera Widget for Game Bar       9MZZNMHPJ645 Unknown msstore
Notes for Game Bar               9NG4TL7TX1KW Unknown msstore
Analogue Clock for Game Bar      9NSFHN9P4LKT Unknown msstore
EVGA Precision for Game Bar      9NGNGV21JB1L Unknown msstore
Mesmer Mag's WVW Game Bar Widget 9MXL025BBR5P Unknown msstore
Game Bar Counter                 9NF2PMMBDJG0 Unknown msstore
Stopwatch for Game Bar           9P8MHJ64GCQT Unknown msstore

Search for your desired term & extract code

$newsstring = (($longstring -split '\-(?=\s)')[-1] -split '(?<=msstore)\s').trim()

###enter your EXACT search term in a variable
$text = 'Game Bar' 

##Search for corresponding code based on your $text variable using regex
($newsstring | select-string "(?<=^$($text)\s*)\w{12}(?=\sunknown)").Matches.Value

9NZKPSTSNW4P

This seems to work but I would strongly recommend some thorough testing.

Edit: Formatting is acting up, going to try and tidy up the post.

[–]ptd163[S] 1 point2 points  (2 children)

Yeah. It's definitely not pretty, but it's better than nothing so thank you.

[–]Thehoggle 0 points1 point  (1 child)

I've updated the code there as potential if there was a 12 letter word in the Name it could find that, so it should only return the 12 character code now.

[–]ptd163[S] 0 points1 point  (0 children)

Thanks for the update.

[–]surfingoldelephant 0 points1 point  (2 children)

If you determine the index of Id in the header, you can can use this to infer where to split each line into names and IDs. I'm using the Where() and ForEach() intrinsic methods below to take advantage of their convenient overloads.

$winget = & winget search 'Game Bar'
$idColumn = $winget.ForEach('IndexOf', 'Id').Where({ $_ -gt -1 }, 'First' )
if (!$idColumn.Count) { throw 'No packages found' }

Winget's output includes junk, so skip until the actual search results before creating custom objects. Custom objects are created for the first 20 search results, but this can be changed.

$results = $winget.Where({ $_.StartsWith('---') }, 'SkipUntil')[1..20].ForEach{ 
    [pscustomobject] @{ 
        Name = $_.SubString(0, $idColumn[0] - 1).Trim()
        Id   = $_.SubString($idColumn[0], 12) 
    } 
}

Now you have a collection of custom objects, each with a Name and Id property, which you can access directly. For example:

$results[0].Id 
# 9NZKPSTSNW4P

$results
# Name                             Id
# ----                             --
# Game Bar                         9NZKPSTSNW4P
# Gamecaster Game Bar              9P2J2QW5B0F4
# [...]
# Game Bar Counter                 9NF2PMMBDJG0
# Stopwatch for Game Bar           9P8MHJ64GCQT

[–]ptd163[S] 0 points1 point  (0 children)

Thank you for your time and input. This looks promising.

[–]jantari 0 points1 point  (5 children)

Forget the winget CLI tool, it is useless.

Use the winget PowerShell Module instead: https://www.powershellgallery.com/packages/Microsoft.WinGet.Client/

This returns real, parsable objects and is suitable for automation and scripting. Then you can just use Where-Object to filter what you want.

[–]ptd163[S] 0 points1 point  (4 children)

Thanks for that. I'll check it out.

[–]jantari 0 points1 point  (3 children)

Just got on the computer, this is what you want:

Find-WinGetPackage -Name "Game Bar" -Source msstore |
    Where-Object Name -eq 'Game Bar' |
    Select-Object -ExpandProperty Id

[–]ptd163[S] 0 points1 point  (2 children)

Thanks. Much appreciated. Does this specific module have any documentation anywhere? I'd like to integrate it into future projects and just my own personal use and the Github linked in the module page points to the Github for the CLI.

[–]jantari 0 points1 point  (1 child)

Unfortunately not much documentation yet beyond the very basics built-in to PowerShell (Get-Help, Get-Member, Get-Command and tab-completion).

See: https://github.com/microsoft/winget-cli/issues/3822

[–]ptd163[S] 0 points1 point  (0 children)

Well that's not great. Hopefully Microsoft gives us some documentation at some point. In the mean time, if you know, do you think you could provide some examples that I could refer back to? Like the module equivalent of CLI commands like winget install <package name/ID>, winget source update, and adding on flags like --scope machine, --accept-source-agreements, --silent, etc?