Cobalt.psm1

# Module created by Microsoft.PowerShell.Crescendo
Function Get-WinGetSource
{
[CmdletBinding()]

param(
[Parameter()]
[string]$Name
    )

BEGIN {
    $__PARAMETERMAP = @{
        Name = @{ OriginalName = '--name='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { 
                        param ($output)
                        if ($output) {
                            $output | ConvertFrom-Json
                        }
                     } }
    }
}
PROCESS {
    $__commandArgs = @(
        "source"
        "export"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Return WinGet package sources

.PARAMETER Name
Source Name



#>

}

Function Register-WinGetSource
{
[CmdletBinding()]

param(
[Parameter(Mandatory=$true)]
[string]$Name,
[Parameter(Mandatory=$true)]
[string]$Argument
    )

BEGIN {
    $__PARAMETERMAP = @{
        Name = @{ OriginalName = '--name='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Argument = @{ OriginalName = '--arg='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { 
                        param ($output)
                        if ($output) {
                            if ($output[-1] -ne 'Done') {
                                Write-Error ($output -join "`r`n")
                            }
                        }
                     } }
    }
}
PROCESS {
    $__commandArgs = @(
        "source"
        "add"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Register a new WinGet package source

.PARAMETER Name
Source Name


.PARAMETER Argument
Source Argument



#>

}

Function Unregister-WinGetSource
{
[CmdletBinding()]

param(
[Parameter(ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
[string]$Name
    )

BEGIN {
    $__PARAMETERMAP = @{
        Name = @{ OriginalName = '--name='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { 
                        param ($output)
                        if ($output) {
                            if ($output[-1] -match 'Did not find a source') {
                                Write-Error ($output -join "`r`n")
                            }
                        }
                     } }
    }
}
PROCESS {
    $__commandArgs = @(
        "source"
        "remove"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Unegister an existing WinGet package source

.PARAMETER Name
Source Name



#>

}

Function Install-WinGetPackage
{
[CmdletBinding()]

param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$ID,
[Parameter()]
[switch]$Exact,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Source,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Version
    )

BEGIN {
    $__PARAMETERMAP = @{
        ID = @{ OriginalName = '--id='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Exact = @{ OriginalName = '--exact'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
        Source = @{ OriginalName = '--source='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Version = @{ OriginalName = '--version='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    if ($output) {
        if ($output -match $languageData.InstallerFailedWithCode) {
            # Only show output that matches or comes after the 'failed' keyword
            Write-Error ($output[$output.IndexOf($($output -match $languageData.InstallerFailedWithCode | Select-Object -First 1))..($output.Length-1)] -join "`r`n")
        } else {
            $output | ForEach-Object {
                if ($_ -match 'Found .+ \[(?<id>[\S]+)\] Version (?<version>[\S]+)' -and $Matches.id -and $Matches.version) {
                    [pscustomobject]@{
                        ID = $Matches.id
                        Version = $Matches.version
                    }
                }
            }
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "install"
        "--accept-package-agreements"
        "--accept-source-agreements"
        "--silent"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Install a new package with WinGet

.PARAMETER ID
Package ID


.PARAMETER Exact
Search by exact package name


.PARAMETER Source
Package Source


.PARAMETER Version
Package Version



#>

}

Function Get-WinGetPackage
{
[CmdletBinding()]

param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$ID,
[Parameter()]
[switch]$Exact,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Source
    )

BEGIN {
    $__PARAMETERMAP = @{
        ID = @{ OriginalName = '--id='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Exact = @{ OriginalName = '--exact'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
        Source = @{ OriginalName = '--source='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    $nameHeader = $output -Match "^$($languageData.SearchName)"

    if ($nameHeader) {

        $headerLine = $output.IndexOf(($nameHeader | Select-Object -First 1))

        if ($headerLine -ne -1) {
            $idIndex = $output[$headerLine].IndexOf(($languageData.SearchID))
            $versionIndex = $output[$headerLine].IndexOf(($languageData.SearchVersion))
            $availableIndex = $output[$headerLine].IndexOf(($languageData.AvailableHeader))
            $sourceIndex = $output[$headerLine].IndexOf(($languageData.SearchSource))

            # Stop gathering version data at the 'Available' column if it exists, if not continue on to the 'Source' column (if it exists)
            $versionEndIndex = $(
                if ($availableIndex -ne -1) {
                    $availableIndex
                } else {
                    $sourceIndex
                }
            )

            # Only attempt to parse output if it contains a 'version' column
            if ($versionIndex -ne -1) {
                # The -replace cleans up errant characters that come from WinGet's poor treatment of truncated columnar output
                ($output | Select-String -Pattern $languageData.AvailableUpgrades,'--include-unknown' -NotMatch) -replace '[^i\p{IsBasicLatin}]+',' ' | Select-Object -Skip ($headerLine+2) | ForEach-Object {
                    Remove-Variable -Name 'package' -ErrorAction SilentlyContinue

                    $package = [ordered]@{
                        ID = $_.SubString($idIndex,$versionIndex-$idIndex).Trim()
                    }

                    if ($package) {
                        # I'm so sorry, blame WinGet
                        # If neither the 'Available' or 'Source' column exist, gather version data to the end of the string
                        $package.Version = $(
                            if ($versionEndIndex -ne -1) {
                                $_.SubString($versionIndex,$versionEndIndex-$versionIndex)
                            } else {
                                $_.SubString($versionIndex)
                            }
                        ).Trim() -replace '[^\.\d]'

                        # Only attempt to add 'Available Version' data if the column exists
                        if ($availableIndex -ne -1) {
                            $package.Available = $(
                                if ($sourceIndex -ne -1) {
                                    $_.SubString($availableIndex,$sourceIndex-$availableIndex)
                                } else {
                                    $_.SubString($availableIndex)
                                }
                            ).Trim() -replace '[^\.\d]'
                        }

                        # If the 'Source' column was included in the output, include it in our output, too
                        if (($sourceIndex -ne -1) -And ($_.Length -ge $sourceIndex)) {
                            $package.Source = $_.SubString($sourceIndex).Trim() -split ' ' | Select-Object -Last 1
                        }

                        [pscustomobject]$package
                    }
                }
            }
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "list"
        "--accept-source-agreements"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Get a list of installed WinGet packages

.PARAMETER ID
Package ID


.PARAMETER Exact
Search by exact package name


.PARAMETER Source
Package Source



#>

}

Function Find-WinGetPackage
{
[CmdletBinding()]

param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$ID,
[Parameter()]
[switch]$Exact,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Source
    )

BEGIN {
    $__PARAMETERMAP = @{
        ID = @{ OriginalName = '--id='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Exact = @{ OriginalName = '--exact'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
        Source = @{ OriginalName = '--source='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    $nameHeader = $output -Match "^$($languageData.SearchName)"

    if ($nameHeader) {

        $headerLine = $output.IndexOf(($nameHeader | Select-Object -First 1))

        if ($headerLine -ne -1) {
            $idIndex = $output[$headerLine].IndexOf(($languageData.SearchID))
            $versionIndex = $output[$headerLine].IndexOf(($languageData.SearchVersion))
            $availableIndex = $output[$headerLine].IndexOf(($languageData.AvailableHeader))
            $sourceIndex = $output[$headerLine].IndexOf(($languageData.SearchSource))

            # Stop gathering version data at the 'Available' column if it exists, if not continue on to the 'Source' column (if it exists)
            $versionEndIndex = $(
                if ($availableIndex -ne -1) {
                    $availableIndex
                } else {
                    $sourceIndex
                }
            )

            # Only attempt to parse output if it contains a 'version' column
            if ($versionIndex -ne -1) {
                # The -replace cleans up errant characters that come from WinGet's poor treatment of truncated columnar output
                ($output | Select-String -Pattern $languageData.AvailableUpgrades,'--include-unknown' -NotMatch) -replace '[^i\p{IsBasicLatin}]+',' ' | Select-Object -Skip ($headerLine+2) | ForEach-Object {
                    Remove-Variable -Name 'package' -ErrorAction SilentlyContinue

                    $package = [ordered]@{
                        ID = $_.SubString($idIndex,$versionIndex-$idIndex).Trim()
                    }

                    if ($package) {
                        # I'm so sorry, blame WinGet
                        # If neither the 'Available' or 'Source' column exist, gather version data to the end of the string
                        $package.Version = $(
                            if ($versionEndIndex -ne -1) {
                                $_.SubString($versionIndex,$versionEndIndex-$versionIndex)
                            } else {
                                $_.SubString($versionIndex)
                            }
                        ).Trim() -replace '[^\.\d]'

                        # Only attempt to add 'Available Version' data if the column exists
                        if ($availableIndex -ne -1) {
                            $package.Available = $(
                                if ($sourceIndex -ne -1) {
                                    $_.SubString($availableIndex,$sourceIndex-$availableIndex)
                                } else {
                                    $_.SubString($availableIndex)
                                }
                            ).Trim() -replace '[^\.\d]'
                        }

                        # If the 'Source' column was included in the output, include it in our output, too
                        if (($sourceIndex -ne -1) -And ($_.Length -ge $sourceIndex)) {
                            $package.Source = $_.SubString($sourceIndex).Trim() -split ' ' | Select-Object -Last 1
                        }

                        [pscustomobject]$package
                    }
                }
            }
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "search"
        "--accept-source-agreements"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Find a list of available WinGet packages

.PARAMETER ID
Package ID


.PARAMETER Exact
Search by exact package name


.PARAMETER Source
Package Source



#>

}

Function Update-WinGetPackage
{
[CmdletBinding()]

param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$ID,
[Parameter()]
[switch]$Exact,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Source,
[Parameter()]
[switch]$All
    )

BEGIN {
    $__PARAMETERMAP = @{
        ID = @{ OriginalName = '--id='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Exact = @{ OriginalName = '--exact'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
        Source = @{ OriginalName = '--source='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        All = @{ OriginalName = '--all'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    if ($output) {
        if ($output -match $languageData.InstallerFailedWithCode) {
            # Only show output that matches or comes after the 'failed' keyword
            Write-Error ($output[$output.IndexOf($($output -match $languageData.InstallerFailedWithCode | Select-Object -First 1))..($output.Length-1)] -join "`r`n")
        } else {
            $output | ForEach-Object {
                if ($_ -match 'Found .+ \[(?<id>[\S]+)\] Version (?<version>[\S]+)' -and $Matches.id -and $Matches.version) {
                    [pscustomobject]@{
                        ID = $Matches.id
                        Version = $Matches.version
                    }
                }
            }
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "upgrade"
        "--accept-source-agreements"
        "--silent"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Updates an installed package to the latest version

.PARAMETER ID
Package ID


.PARAMETER Exact
Search by exact package name


.PARAMETER Source
Package Source


.PARAMETER All
Upgrade all packages



#>

}

Function Uninstall-WinGetPackage
{
[CmdletBinding()]

param(
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$ID,
[Parameter()]
[switch]$Exact,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[string]$Source
    )

BEGIN {
    $__PARAMETERMAP = @{
        ID = @{ OriginalName = '--id='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Exact = @{ OriginalName = '--exact'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
        Source = @{ OriginalName = '--source='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    if ($output) {
        if ($output -match $languageData.UninstallFailedWithCode) {
            # Only show output that matches or comes after the 'failed' keyword
            Write-Error ($output[$output.IndexOf($($output -match $languageData.UninstallFailedWithCode | Select-Object -First 1))..($output.Length-1)] -join "`r`n")
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "uninstall"
        "--accept-source-agreements"
        "--silent"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Uninstall an existing package with WinGet

.PARAMETER ID
Package ID


.PARAMETER Exact
Search by exact package name


.PARAMETER Source
Package Source



#>

}

Function Get-WinGetPackageInfo
{
[CmdletBinding(DefaultParameterSetName='Default')]

param(
[Parameter(Position=0,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]
[Parameter(ParameterSetName="Default")]
[Parameter(ParameterSetName="Versions")]
[string]$ID,
[Parameter()]
[Parameter(ParameterSetName="Default")]
[Parameter(ParameterSetName="Versions")]
[switch]$Exact,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName="Default")]
[Parameter(ParameterSetName="Versions")]
[string]$Version,
[Parameter(ValueFromPipelineByPropertyName=$true)]
[Parameter(ParameterSetName="Default")]
[Parameter(ParameterSetName="Versions")]
[string]$Source,
[Parameter(ParameterSetName='Versions')]
[switch]$Versions
    )

BEGIN {
    $__PARAMETERMAP = @{
        ID = @{ OriginalName = '--id='; OriginalPosition = '0'; Position = '0'; ParameterType = [string]; NoGap = $True }
        Exact = @{ OriginalName = '--exact'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
        Version = @{ OriginalName = '--version='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Source = @{ OriginalName = '--source='; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [string]; NoGap = $True }
        Versions = @{ OriginalName = '--versions'; OriginalPosition = '0'; Position = '2147483647'; ParameterType = [switch]; NoGap = $False }
    }

    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { 
                            param ( $output )

                            $packageInfo = @{}

                            $output | Select-String -AllMatches -Pattern '^\s*([\w\s]+):\s(.+)$' | ForEach-Object -MemberName Matches | ForEach-Object{
                                $match = ($_.Groups | Select-Object -Skip 1).Value
                                $packageInfo.add($match[0],$match[1])
                            }

                            $packageInfo
                         } }
        Versions = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    if ($output) {
        if ($output | Select-String -Pattern $languageData.GetManifestResultVersionNotFound) {
            # Only show output that matches or comes after the 'failed' keyword
            Write-Error ($output[$output.IndexOf($($output | Select-String -Pattern $languageData.GetManifestResultVersionNotFound | Select-Object -First 1))..($output.Length-1)] -join "`r`n")
        } else {
            $versionHeader = $output -Match "^$($languageData.ShowVersion)"

            if ($versionHeader) {

                $headerLine = $output.IndexOf(($versionHeader | Select-Object -First 1))

                if ($headerLine -ne -1) {
                    $output | Select-Object -Skip ($headerLine+2)
                }
            }
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "show"
        "--accept-source-agreements"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Shows information on a specific WinGet package

.PARAMETER ID
Package ID


.PARAMETER Exact
Search by exact package name


.PARAMETER Version
Package Version


.PARAMETER Source
Package Source


.PARAMETER Versions
Show available versions of the package



#>

}

Function Get-WinGetPackageUpdate
{
[CmdletBinding()]

param(    )

BEGIN {
    $__PARAMETERMAP = @{}
    $__outputHandlers = @{
        Default = @{ StreamOutput = $False; Handler = { param ($output)
    $language = (Get-UICulture).Name

    $languageData = $(
        $hash = @{}

        $(try {
            # We have to trim the leading BOM for .NET's XML parser to correctly read Microsoft's own files - go figure
            ([xml](((Invoke-WebRequest -Uri "https://raw.githubusercontent.com/microsoft/winget-cli/master/Localization/Resources/$language/winget.resw" -ErrorAction Stop ).Content -replace "\uFEFF", ""))).root.data
        } catch {
            # Fall back to English if a locale file doesn't exist
            (
                ('SearchName','Name'),
                ('SearchID','Id'),
                ('SearchVersion','Version'),
                ('AvailableHeader','Available'),
                ('SearchSource','Source'),
                ('ShowVersion','Version'),
                ('GetManifestResultVersionNotFound','No version found matching:'),
                ('InstallerFailedWithCode','Installer failed with exit code:'),
                ('UninstallFailedWithCode','Uninstall failed with exit code:'),
                ('AvailableUpgrades','upgrades available.')
            ) | ForEach-Object {[pscustomobject]@{name = $_[0]; value = $_[1]}}
        }) | ForEach-Object {
            # Convert the array into a hashtable
            $hash[$_.name] = $_.value
        }

        $hash
    )

    $nameHeader = $output -Match "^$($languageData.SearchName)"

    if ($nameHeader) {

        $headerLine = $output.IndexOf(($nameHeader | Select-Object -First 1))

        if ($headerLine -ne -1) {
            $idIndex = $output[$headerLine].IndexOf(($languageData.SearchID))
            $versionIndex = $output[$headerLine].IndexOf(($languageData.SearchVersion))
            $availableIndex = $output[$headerLine].IndexOf(($languageData.AvailableHeader))
            $sourceIndex = $output[$headerLine].IndexOf(($languageData.SearchSource))

            # Stop gathering version data at the 'Available' column if it exists, if not continue on to the 'Source' column (if it exists)
            $versionEndIndex = $(
                if ($availableIndex -ne -1) {
                    $availableIndex
                } else {
                    $sourceIndex
                }
            )

            # Only attempt to parse output if it contains a 'version' column
            if ($versionIndex -ne -1) {
                # The -replace cleans up errant characters that come from WinGet's poor treatment of truncated columnar output
                ($output | Select-String -Pattern $languageData.AvailableUpgrades,'--include-unknown' -NotMatch) -replace '[^i\p{IsBasicLatin}]+',' ' | Select-Object -Skip ($headerLine+2) | ForEach-Object {
                    Remove-Variable -Name 'package' -ErrorAction SilentlyContinue

                    $package = [ordered]@{
                        ID = $_.SubString($idIndex,$versionIndex-$idIndex).Trim()
                    }

                    if ($package) {
                        # I'm so sorry, blame WinGet
                        # If neither the 'Available' or 'Source' column exist, gather version data to the end of the string
                        $package.Version = $(
                            if ($versionEndIndex -ne -1) {
                                $_.SubString($versionIndex,$versionEndIndex-$versionIndex)
                            } else {
                                $_.SubString($versionIndex)
                            }
                        ).Trim() -replace '[^\.\d]'

                        # Only attempt to add 'Available Version' data if the column exists
                        if ($availableIndex -ne -1) {
                            $package.Available = $(
                                if ($sourceIndex -ne -1) {
                                    $_.SubString($availableIndex,$sourceIndex-$availableIndex)
                                } else {
                                    $_.SubString($availableIndex)
                                }
                            ).Trim() -replace '[^\.\d]'
                        }

                        # If the 'Source' column was included in the output, include it in our output, too
                        if (($sourceIndex -ne -1) -And ($_.Length -ge $sourceIndex)) {
                            $package.Source = $_.SubString($sourceIndex).Trim() -split ' ' | Select-Object -Last 1
                        }

                        [pscustomobject]$package
                    }
                }
            }
        }
    }
 } }
    }
}
PROCESS {
    $__commandArgs = @(
        "upgrade"
    )
    $__boundparms = $PSBoundParameters
    $MyInvocation.MyCommand.Parameters.Values.Where({$_.SwitchParameter -and $_.Name -notmatch "Debug|Whatif|Confirm|Verbose" -and ! $PSBoundParameters[$_.Name]}).ForEach({$PSBoundParameters[$_.Name] = [switch]::new($false)})
    if ($PSBoundParameters["Debug"]){wait-debugger}
    foreach ($paramName in $PSBoundParameters.Keys|Sort-Object {$__PARAMETERMAP[$_].OriginalPosition}) {
        $value = $PSBoundParameters[$paramName]
        $param = $__PARAMETERMAP[$paramName]
        if ($param) {
            if ( $value -is [switch] ) { $__commandArgs += if ( $value.IsPresent ) { $param.OriginalName } else { $param.DefaultMissingValue } }
            elseif ( $param.NoGap ) { $__commandArgs += "{0}""{1}""" -f $param.OriginalName, $value }
            else { $__commandArgs += $param.OriginalName; $__commandArgs += $value |Foreach-Object {$_}}
        }
    }
    $__commandArgs = $__commandArgs|Where-Object {$_}
    if ($PSBoundParameters["Debug"]){wait-debugger}
    if ( $PSBoundParameters["Verbose"]) {
         Write-Verbose -Verbose -Message WinGet
         $__commandArgs | Write-Verbose -Verbose
    }
    $__handlerInfo = $__outputHandlers[$PSCmdlet.ParameterSetName]
    if (! $__handlerInfo ) {
        $__handlerInfo = $__outputHandlers["Default"] # Guaranteed to be present
    }
    $__handler = $__handlerInfo.Handler
    if ( $PSCmdlet.ShouldProcess("WinGet")) {
        if ( $__handlerInfo.StreamOutput ) {
            & "WinGet" $__commandArgs | & $__handler
        }
        else {
            $result = & "WinGet" $__commandArgs
            & $__handler $result
        }
    }
  } # end PROCESS

<#


.DESCRIPTION
Get a list of installed WinGet packages

#>

}

Export-ModuleMember -Function Get-WinGetSource, Register-WinGetSource, Unregister-WinGetSource, Install-WinGetPackage, Get-WinGetPackage, Find-WinGetPackage, Update-WinGetPackage, Uninstall-WinGetPackage, Get-WinGetPackageInfo, Get-WinGetPackageUpdate