functions/Get-WGPackage.ps1
<#
As was made evident by Issue #1, Winget output is not always in English, and not every property is returned from the Winget show command. I think the best course of action is to turn the raw winget data into a list object and then use the Find() method to find specific values like Version,Description, and Moniker. However there is still an issue of what to do with non-English results. #> Function Get-WGPackage { [cmdletbinding(DefaultParameterSetName = "name")] [OutputType("WGPackage")] Param( [Parameter( ParameterSetName = "name", Position = 0, Mandatory, ValueFromPipelineByPropertyName, HelpMessage = "Specify the package name" )] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter( ParameterSetName = "id", ValueFromPipelineByPropertyName, HelpMessage = "Specify the package ID" )] [ValidateNotNullOrEmpty()] [string]$ID, [Parameter( ParameterSetName = "moniker", HelpMessage = "Specify the moniker" )] [ValidateNotNullOrEmpty()] [string]$Moniker, [Parameter( ParameterSetname = "input", ValueFromPipeline, HelpMessage = "Pipe a winget search to this function" )] [object[]]$InputObject, [Parameter(HelpMessage = "Specify a winget source")] [ValidateNotNullOrEmpty()] [string]$Source = "winget" ) Begin { Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Starting $($myinvocation.mycommand)" #some regex patterns [regex]$rxIDAll = "(?<=\s)[\w-+]{3,}\.[\w-+]{3,}(\.[\w-+]{3,})?" Write-Verbose "[$((Get-Date).TimeofDay) BEGIN ] Using source $source" $winget = Get-WGPath $cmdText = "$winget show --source $source" Switch ($PSCmdlet.ParameterSetName) { "Name" { if ($name) { $cmdText += " --name '$name'" } } "ID" { $cmdText += " --id $id" } "Moniker" { $cmdText += " --moniker $moniker" } } #create a scriptblock $sb = [scriptblock]::create($cmdText) } #begin Process { Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Using Parameter set $($PSCmdlet.ParameterSetName)" if ($InputObject) { Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing winget output by input" $data = $InputObject | Where-Object { $rxIDAll.IsMatch($InputObject) } | ForEach-Object { $id = $rxIDAll.Match($_).Value if ($id -match "\w+") { Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Show $id" &$winget show --id $id --source $source | Where-Object {$_ -notmatch "(\d+%|\d MB|\s+)$" -and $_.length -gt 0} } else { write-Warning $_ } } Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processed $($data.count) item(s)" } else { Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Invoking: $cmdtext" $data = Invoke-Command -ScriptBlock $sb | Where-Object {$_ -notmatch "(\d+%|\d MB|\s+)$" -and $_.length -gt 0} } if ($data -match "Multiple apps found") { Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Multiple packages found" #Get all the IDS $IDs = $rxIDAll.Matches($data).value Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Processing $($IDS.count) packages" $out = foreach ($item in $ids) { #get the exact package to avoid problems when there are duplicate names Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Retrieving $item" _convert (&$winget show -e $item | Where-Object {$_ -notmatch "(\d+%|\d MB|\s+)$" -and $_.length -gt 0}) } } #if multiple found elseif ($data -match "no package found") { if ($cmdText) { Write-Warning $cmdText } elseif ($InputObject) { Write-Warning ($InputObject | Out-String) } Write-Warning ($data | Out-String).Trim() } elseif ($data) { Write-Verbose "[$((Get-Date).TimeofDay) PROCESS] Converting winget data" $data | Out-String | Write-Verbose $out = _convert $data } #else #insert the typename $out } #process End { Write-Verbose "[$((Get-Date).TimeofDay) END ] Ending $($myinvocation.mycommand)" } #end } |