1

I've been grabbing my hair on this one (not much left).

I'm trying get the last characters on a powershell output.

Here's my basic code as example

$VLCVersion = winget search --exact VideoLAN.VLC --source winget

Foreach($line in $VLCVersion){ If($line -like “VLC”) { Write-host $line} }

$line

Example:

  • winget search --exact VideoLAN.VLC --source winget

Result: It gives me the following result

Name Id Version VLC media player VideoLAN.VLC 3.0.17.4

I remove all the lines except the one related to 'VLC' to get to this

VLC media player VideoLAN.VLC 3.0.17.4

How do I get the version number in it's own string

I only want 3.0.17.4 to show.

  • for this specific case this seems to work just fine `[version] ($VLCVersion[-1] -split '\s' | Select-Object -Last 1)` but don't that will work for all winget queries – Santiago Squarzon Sep 28 '22 at 14:08
  • 1
    Oh my hat. It works perfect. I'll adjust my script a bit to check if version output is available. I know of some that don't have version info, but this is a great help. TX – Marius van Deventer Sep 28 '22 at 14:18
  • Good luck with your hair recovery :) – Santiago Squarzon Sep 28 '22 at 14:20
  • 1
    @SantiagoSquarzon might be a good idea to post your comment as an answer – Matthias Sep 28 '22 at 14:51
  • @Matthias done, tho I wouldnt consider a robust solution to the problem (which is why I didnt want to post an answer before) – Santiago Squarzon Sep 28 '22 at 15:01
  • oh I see alright, fair enough, hopefully it can still help someone else – Matthias Sep 28 '22 at 15:04
  • The program seems pretty dumb as far as output. I think powershell cmdlets are in the works. I guess you can parse it by the position of the headers, which changes. Sometimes there's a Match header. – js2010 Sep 28 '22 at 15:39
  • Thanks All. Tested last night on several apps we want to manage via Winget. And the select few apps we want is getting all the info I need. The script checks for new versions of the apps in winget source and then if different it'll update to the latest one. – Marius van Deventer Sep 29 '22 at 07:27

3 Answers3

0

I don't consider this a robust enough solution but for this particular case, you can accomplish it via simply splitting on white space and then getting the last token. You can then use TryParse(String, Version) to get the correct object:

$wget    = winget search --exact VideoLAN.VLC --source winget
$version = $wget[-1] -split '\s'

[ref] $ref = $null
if([version]::TryParse($version[-1], $ref)) {
    $ref.Value
}
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37
0

Here's a parsing attempt. Bizarrely, the first blank line has backspaces and a dash in it. Return is like continue for foreach-object.

# invoke-winget.ps1

$first = 1

$out = "   `b-`b ", 
'Name                     Id                   Version',
'------------------------------------------------------',
'x264                     VideoLAN.x264        3098',
'VLC media player nightly VideoLAN.VLC.Nightly 4.0.0',
'VLC media player         VideoLAN.VLC         3.0.17.4'

$out = winget $args

$out | ForEach-Object {
    if ($_ -match '^   [\b]-[\b] |^---') { 
        return # skip first blank line or dashes line
    } 
    elseif ($first -eq 1) {
        $NamePos = $_.IndexOf("Name")
        $IdPos = $_.IndexOf("Id")
        $VersionPos = $_.IndexOf("Version")
        $first = 0
    }
    else {
        $name = $_.substring($NamePos,$IdPos-$NamePos).Trim()
        $id = $_.substring($IdPos,$VersionPos-$IdPos).Trim()
        $version = $_.substring($VersionPos,$_.length-$VersionPos).Trim() ) -replace 'Tag: .*'
        [pscustomobject]@{Name = $name; Id = $Id; Version = $version}
    }
}

Examples (3098 can't be converted to [version]):

.\invoke-winget search VideoLAN --source winget


Name                     Id                   Version
----                     --                   -------
x264                     VideoLAN.x264        3098
VLC media player nightly VideoLAN.VLC.Nightly 4.0.0
VLC media player         VideoLAN.VLC         3.0.17.4


# case sensitive
.\invoke-winget search --exact VideoLAN.VLC --source winget

Name             Id           Version
----             --           -------
VLC media player VideoLAN.VLC 3.0.17.4


.\invoke-winget search --exact VideoLAN.VLC --source winget | % version

3.0.17.4
js2010
  • 23,033
  • 6
  • 64
  • 66
0

Created this quick snippet and it does what I need. In my larger script I check for 'null' value for winget source version , and then do other checks. I use a combination of Registry and File version checks before Updating the apps. VLC in this instance give 'false' DisplayVersion in registry 3.0.17.0 where the fileversion ,VLC.exe, though is correct at 3.0.17.4 as per Winget Source.

$VLCWinget = .\winget.exe search --exact VideoLAN.VLC --source winget
$VLCVersion = $VLCWinget[-1] -split '\s' | Select-Object -Last 1
$VLCVersion