diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 890c6f4..e3578f6 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -34,10 +34,11 @@ jobs: path: C:\Users\runneradmin\Documents\PowerShell\Modules\WinGet\ - name: Install WinGet shell: pwsh - run: Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/ethanbergstrom/Cobalt/master/Install-WinGet.ps1')) - - name: Install Cobalt - run: Install-Module Cobalt -Force + run: .\Install-WinGet.ps1 + - name: Install Microsoft.WinGet.Client + run: Install-Module Microsoft.WinGet.Client -Force - name: Test with Pester + shell: pwsh run: | Invoke-Pester -Configuration (New-PesterConfiguration -Hashtable @{ Run = @{ @@ -84,9 +85,9 @@ jobs: with: name: module path: '~/.local/share/powershell/Modules/WinGet' - - name: Install Cobalt + - name: Install Microsoft.WinGet.Client shell: pwsh - run: Install-Module Cobalt -Force + run: Install-Module Microsoft.WinGet.Client -Force - name: Publish Module env: NUGET_KEY: ${{ secrets.NUGET_KEY }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 62fc411..1901b93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ## Unreleased +## 0.1.0 - 2023-06-04 - Leverage official WinGet module and PowerShell 5.1 Deprecation +### Changed +* Interaction with the underlying WinGet provider now handled by the official Microsoft PowerShell module +* Package ID search is now case-insensitive +### Removed +* Due to the official Microsoft PowerShell module only supporting PowerShell v7+, this provider will no longer support PowerShell 5.1 or other pre-PowerShell v7 platforms +* Due to no longer supporting PowerShell 5.1, PowerShell Desired State Configuration is no longer supported either +* Additional package metadata is not currently supported by the official WinGet PowerShell module, so removing support for the `-Detailed` switch + ## 0.0.8 - 2022-05-14 - Performance Improvement ### Changed * No longer include package summary and download URL in package data by default, now accessible with the `-Detailed` switch @@ -40,7 +49,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), ### Changed * Merged in structural changes from `ChocolateyGet` -* WinGet CLI interaction now handled via the PowerShell Crescendo module `Cobalt` +* WinGet interaction now handled via the PowerShell module `Microsoft.WinGet.Client` ## 0.0.1 - 2020-05-20 - Initial Release ### Added diff --git a/Install-WinGet.ps1 b/Install-WinGet.ps1 new file mode 100644 index 0000000..6feaee6 --- /dev/null +++ b/Install-WinGet.ps1 @@ -0,0 +1,61 @@ +Install-Module NtObjectManager -Force +Import-Module appx -UseWindowsPowerShell -WarningAction SilentlyContinue + +# GitHub release information +$appxPackageName = 'Microsoft.DesktopAppInstaller' +$msWinGetLatestReleaseURL = 'https://github.com/microsoft/winget-cli/releases/expanded_assets/v1.4.11071' +$msWinGetMSIXBundlePath = ".\$appxPackageName.msixbundle" +$msWinGetLicensePath = ".\$appxPackageName.license.xml" + +# Workaround for no Microsoft Store on Windows Server - I dont know a great way to source this information dynamically +$architecture = 'x64' +$msStoreDownloadAPIURL = 'https://store.rg-adguard.net/api/GetFiles' +$msWinGetStoreURL = 'https://www.microsoft.com/en-us/p/app-installer/9nblggh4nns1' +$msVCLibPattern = "*Microsoft.VCLibs*UWPDesktop*$architecture*appx*" +$msVCLibDownloadPath = '.\Microsoft.VCLibs.UWPDesktop.appx' +$msUIXamlPattern = "*Microsoft.UI.Xaml*$architecture*appx*" +$msUIXamlDownloadPath = '.\Microsoft.UI.Xaml.appx' +$msWinGetExe = 'winget' +$wingetExecAliasPath = "C:\Windows\System32\$msWinGetExe.exe" + +$msWinGetLatestRelease = Invoke-WebRequest -Uri $msWinGetLatestReleaseURL + +# Download the latest MSIX bundle and matching license from GitHub +$msWinGetLatestRelease.links | + Where-Object href -like '*msixbundle' | + Select-Object -Property @{ + Name = 'URI'; + Expression = {$msWinGetLatestRelease.BaseResponse.headers.Server.Product.Name+$_.href} + } | ForEach-Object {Invoke-WebRequest -Uri $_.URI -OutFile $msWinGetMSIXBundlePath} + +# Hopefully this mitigates the sporadic authentication denied errors from GitHub's CDN +Start-Sleep -Seconds 10 + +$msWinGetLatestRelease.links | + Where-Object href -Like '*License*xml' | + Select-Object -Property @{ + Name = 'URI'; + Expression = {$msWinGetLatestRelease.BaseResponse.headers.Server.Product.Name+$_.href} + } | ForEach-Object {Invoke-WebRequest -Uri $_.URI -OutFile $msWinGetLicensePath} + +# Download the VC++ redistrubable for UWP apps from the Microsoft Store +(Invoke-WebRequest -Uri $msStoreDownloadAPIURL -Method Post -Form @{type='url'; url=$msWinGetStoreURL; ring='Retail'; lang='en-US'}).links | + Where-Object OuterHTML -Like $msVCLibPattern | + Sort-Object outerHTML -Descending | + Select-Object -First 1 -ExpandProperty href | + ForEach-Object {Invoke-WebRequest -Uri $_ -OutFile $msVCLibDownloadPath} + +# Download the Windows UI redistrubable from the Microsoft Store +(Invoke-WebRequest -Uri $msStoreDownloadAPIURL -Method Post -Form @{type='url'; url=$msWinGetStoreURL; ring='Retail'; lang='en-US'}).links | +Where-Object OuterHTML -Like $msUIXamlPattern | + Sort-Object outerHTML -Descending | + Select-Object -First 1 -ExpandProperty href | + ForEach-Object {Invoke-WebRequest -Uri $_ -OutFile $msUIXamlDownloadPath} + +# Install the WinGet and it's VC++ .msix with the downloaded license file +Add-AppProvisionedPackage -Online -PackagePath $msWinGetMSIXBundlePath -DependencyPackagePath ($msVCLibDownloadPath,$msUIXamlDownloadPath) -LicensePath $msWinGetLicensePath + +# Force the creation of the execution alias with NtObjectManager, since one isn't generated automatically in the current user session +$appxPackage = Get-AppxPackage Microsoft.DesktopAppInstaller +$wingetTarget = Join-Path -Path $appxPackage.InstallLocation -ChildPath ((Get-AppxPackageManifest $appxPackage).Package.Applications.Application | Where-Object Id -eq $msWinGetExe | Select-Object -ExpandProperty Executable) +NtObjectManager\Set-ExecutionAlias -Path $wingetExecAliasPath -PackageName ($appxPackage.PackageFamilyName) -EntryPoint "$($appxPackage.PackageFamilyName)!$msWinGetExe" -Target $wingetTarget -AppType Desktop -Version 3 diff --git a/README.md b/README.md index ee4b149..0c11519 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ WinGet for PackageManagement facilitates installing WinGet packages from any compatible repository. The provider is heavily influenced by the work of the [ChocolateyGet](https://github.com/jianyunt/ChocolateyGet) project. ## Requirements -Your machine must have at least Windows 10 1709 or Windows 11 and either PowerShell 5.1+ or PowerShell 7.0.1+, and the WinGet CLI utility installed. It may be already installed on your machine, but if not, Microsoft's recommended method for installing WinGet is via the Microsoft Store as part of the [App Installer](https://www.microsoft.com/en-us/p/app-installer/9nblggh4nns1?activetab=pivot:overviewtab) package. +Your machine must have at least Windows 10 1709 or Windows 11, PowerShell 7.0.1+, and the WinGet CLI utility installed. It may be already installed on your machine, but if not, Microsoft's recommended method for installing WinGet is via the Microsoft Store as part of the [App Installer](https://www.microsoft.com/en-us/p/app-installer/9nblggh4nns1?activetab=pivot:overviewtab) package. **The WinGet Package Management Provider does not install the WinGet CLI utility. Please make sure the WinGet CLI utility is functional before attempting to use the WinGet PackageManagement provider!** @@ -18,8 +18,6 @@ Note: Please do **not** use `Import-Module` with Package Management providers, a ### Search for a package ```PowerShell Find-Package OpenJS.NodeJS -Provider WinGet - -Find-Package Mozilla.Firefox -Provider WinGet -Detailed ``` ### Find all available versions of a package @@ -107,66 +105,6 @@ OpenJS.NodeJS 17.2.0 winget ``` -This feature can be combined with a PackageManagement-compatible configuration management system (ex: [PowerShell DSC LCM in 'ApplyAndAutoCorrect' mode](https://docs.microsoft.com/en-us/powershell/scripting/dsc/managing-nodes/metaconfig)) to regularly keep certain packages up to date: -```PowerShell -Configuration MyNode { - Import-DscResource PackageManagement - PackageManagement WinGet { - Name = 'WinGet' - Source = 'PSGallery' - } - PackageManagement NodeJS { - Name = 'OpenJS.NodeJS' - RequiredVersion = 'latest' - ProviderName = 'WinGet' - DependsOn = '[PackageManagement]WinGet' - } -} -``` - -**Please note** - Since PackageManagement doesn't support passing source information when invoking `Get-Package`, the 'latest' functionality **will not work** if the default WinGet package source is removed as a source **and** multiple custom sources are defined. - -Furthermore, if both the default WinGet package source and a custom source are configured, the custom source **will be ignored** when the 'latest' required version is used with `Get-Package`. - -Example PowerShell DSC configuration using the 'latest' required version with a custom source: - -```PowerShell -Configuration MyNode { - Import-DscResource PackageManagement,PackageManagementSource - PackageManagement WinGet { - Name = 'WinGet' - Source = 'PSGallery' - } - PackageManagementSource WinGetPrivateRepo { - Name = 'privateRepo' - ProviderName = 'WinGet' - SourceLocation = 'https://somewhere/out/there/cache' - InstallationPolicy = 'Trusted' - DependsOn = '[PackageManagement]WinGet' - } - PackageManagementSource WinGetRepo { - Name = 'WinGet' - ProviderName = 'WinGet' - Ensure = 'Absent' - DependsOn = '[PackageManagement]WinGet' - } - # The source information wont actually be used by the Get-Package step of the PackageManagement DSC resource check, but it helps make clear to the reader where the package should come from - PackageManagement NodeJS { - Name = 'OpenJS.NodeJS' - ProviderName = 'WinGet' - Source = 'privateRepo' - RequiredVersion = 'latest' - DependsOn = @('[PackageManagementSource]WinGetPrivateRepo', '[PackageManagementSource]WinGetRepo') - } -} -``` - -A working example PowerShell DSC script with automatic package updates can be found [here](https://gist.github.com/ethanbergstrom/9a4a0d29ea0452ef46bba580a7567d98). - -If using the 'latest' functionality, best practice is to either: -* use the default WinGet source -* unregister the default WinGet source in favor of a **single** custom source - ## Known Issues WinGet is still in a preview period, with many features not implemented that are required for a PackageManagement provider to be fully implemented. diff --git a/Test/WinGet.Unit.Tests.ps1 b/Test/WinGet.Unit.Tests.ps1 index c0bc90d..7b5e9b9 100644 --- a/Test/WinGet.Unit.Tests.ps1 +++ b/Test/WinGet.Unit.Tests.ps1 @@ -22,37 +22,12 @@ Describe 'basic package search operations' { It 'returns all available versions of a package' { Find-Package -Provider $WinGet -Name $package -AllVersions | Where-Object {$_.Version -eq $version} | Should -Not -BeNullOrEmpty } - It 'returns additional package metadata' { - Find-Package -Provider $WinGet -Name $package -Detailed | Select-Object -ExpandProperty FullPath | Should -Not -BeNullOrEmpty - } It 'searches for all versions of a package' { Find-Package -Provider $WinGet -Name $package -AllVersions | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty } } } -Describe 'DSC-compliant package installation and uninstallation' { - Context 'without additional arguments' { - BeforeAll { - $package = 'CPUID.HWMonitor' - $version = '1.44' - } - - It 'searches for a specific version of a package' { - Find-Package -Provider $WinGet -Name $package -RequiredVersion $version | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty - } - It 'silently installs a specific version of a package' { - Install-Package -Provider $WinGet -Name $package -RequiredVersion $version -Force | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty - } - It 'finds the locally installed package just installed' { - Get-Package -Provider $WinGet -Name $package -RequiredVersion $version | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty - } - It 'silently uninstalls the locally installed package just installed' { - Uninstall-Package -Provider $WinGet -Name $package -RequiredVersion $version | Where-Object {$_.Name -contains $package} | Should -Not -BeNullOrEmpty - } - } -} - Describe 'pipeline-based package installation and uninstallation' { Context 'without additional arguments' { BeforeAll { diff --git a/src/WinGet.psd1 b/src/WinGet.psd1 index 2b39431..00fd79e 100644 --- a/src/WinGet.psd1 +++ b/src/WinGet.psd1 @@ -1,25 +1,21 @@ @{ RootModule = 'WinGet.psm1' - ModuleVersion = '0.0.8' + ModuleVersion = '0.1.0' GUID = '468ef37a-2557-4c10-92ec-783ec1e41639' Author = 'Ethan Bergstrom' Copyright = '' Description = 'Package Management (OneGet) provider that facilitates installing WinGet packages from any NuGet repository.' # Refuse to load in CoreCLR if PowerShell below 7.0.1 due to regressions with how 7.0 loads PackageManagement DLLs # https://github.com/PowerShell/PowerShell/pull/12203 - PowerShellVersion = if ($PSEdition -eq 'Core') { - '7.0.1' - } else { - '5.1' - } + PowerShellVersion = '7.0.1' RequiredModules = @( @{ ModuleName='PackageManagement' ModuleVersion='1.1.7.2' }, @{ - ModuleName='Cobalt' - ModuleVersion='0.2.0' + ModuleName='Microsoft.WinGet.Client' + ModuleVersion='0.2.1' } ) PrivateData = @{ diff --git a/src/WinGet.psm1 b/src/WinGet.psm1 index 7878f29..af427fc 100644 --- a/src/WinGet.psm1 +++ b/src/WinGet.psm1 @@ -6,7 +6,6 @@ $script:AcceptLicense = "AcceptLicense" $script:Force = "Force" $script:PackageSource = "WinGet" $script:AllVersions = "AllVersions" -$script:Detailed = "Detailed" # Utility variables # Fast Package References are passed between cmdlets in the format of '##' diff --git a/src/private/ConvertTo-SoftwareIdentity.ps1 b/src/private/ConvertTo-SoftwareIdentity.ps1 index d3fafc7..a208395 100644 --- a/src/private/ConvertTo-SoftwareIdentity.ps1 +++ b/src/private/ConvertTo-SoftwareIdentity.ps1 @@ -1,4 +1,4 @@ -# Convert the objects returned from Cobalt into Software Identities (SWIDs). +# Convert the objects returned from Microsoft.WinGet.Client into Software Identities (SWIDs). function ConvertTo-SoftwareIdentity { [CmdletBinding()] param ( @@ -14,7 +14,7 @@ function ConvertTo-SoftwareIdentity { process { Write-Debug ($LocalizedData.ProviderDebugMessage -f ('ConvertTo-SoftwareIdentity')) foreach ($package in $InputObject) { - # Return a new SWID based on the output from Cobalt + # Return a new SWID based on the output from Microsoft.WinGet.Client $packageSource = $( if ($package.source) { $package.source @@ -33,12 +33,6 @@ function ConvertTo-SoftwareIdentity { Source = $packageSource } - if ($request.Options.ContainsKey($script:Detailed)) { - $metadata = Cobalt\Get-WinGetPackageInfo -ID $package.ID -Version $package.Version -Source $packageSource - $swid.Summary = $metadata.Description - $swid.FullPath = $metadata.'Download URL' - } - New-SoftwareIdentity @swid } } diff --git a/src/private/Find-WinGetPackage.ps1 b/src/private/Find-WinGetPackage.ps1 index 6117a5c..7a32a65 100644 --- a/src/private/Find-WinGetPackage.ps1 +++ b/src/private/Find-WinGetPackage.ps1 @@ -21,7 +21,7 @@ function Find-WinGetPackage { Write-Debug ($LocalizedData.ProviderDebugMessage -f ('Find-WinGetPackage')) $options = $request.Options - [array]$RegisteredPackageSources = Cobalt\Get-WinGetSource + [array]$RegisteredPackageSources = Microsoft.WinGet.Client\Get-WinGetSource $selectedSource = $( if ($options -And $options.ContainsKey('Source')) { @@ -58,16 +58,16 @@ function Find-WinGetPackage { $WinGetParams = @{ ID = $Name Source = $selectedSource - Exact = $true + MatchOption = 'EqualsCaseInsensitive' } - # Convert the PSCustomObject output from Cobalt into PackageManagement SWIDs, then filter results by any version requirements + # Convert the PSCustomObject output from Microsoft.WinGet.Client into PackageManagement SWIDs, then filter results by any version requirements # We have to specify the source when converting to SWIDs, because WinGet doesn't return source information when the source is specified - Cobalt\Find-WinGetPackage @WinGetParams | ForEach-Object { + Microsoft.WinGet.Client\Find-WinGetPackage @WinGetParams | ForEach-Object { # If we need to retrieve all versions, perform an additional query to get all available versions, and create a package object for each version if ($RequiredVersion -Or $minimumVersion -Or $maximumVersion -Or $options.ContainsKey($script:AllVersions)) { $package = $_ - $package | Get-WinGetPackageInfo -Versions -Source $selectedSource | Select-Object -Property @{ + $package.AvailableVersions | Select-Object -Property @{ Name = 'ID' Expression = {$package.ID} },@{ diff --git a/src/public/Add-PackageSource.ps1 b/src/public/Add-PackageSource.ps1 index 1dfc80f..21f7a5b 100644 --- a/src/public/Add-PackageSource.ps1 +++ b/src/public/Add-PackageSource.ps1 @@ -19,9 +19,9 @@ function Add-PackageSource { Write-Debug ($LocalizedData.ProviderDebugMessage -f ('Add-PackageSource')) Write-Verbose "New package source: $Name, $Location" - Cobalt\Register-WinGetSource -Name $Name -Argument $Location + Microsoft.WinGet.Client\Register-WinGetSource -Name $Name -Argument $Location - # Cobalt doesn't return anything after new sources are registered, but PackageManagement expects a response + # Microsoft.WinGet.Client doesn't return anything after new sources are registered, but PackageManagement expects a response $packageSource = @{ Name = $Name Location = $Location.TrimEnd("\") diff --git a/src/public/BaseFunctions.ps1 b/src/public/BaseFunctions.ps1 index d8fb39a..33e1e49 100644 --- a/src/public/BaseFunctions.ps1 +++ b/src/public/BaseFunctions.ps1 @@ -22,11 +22,9 @@ function Get-DynamicOptions { switch ($category) { Package { Write-Output -InputObject (New-DynamicOption -Category $category -Name $script:AcceptLicense -ExpectedType Switch -IsRequired $false) - Write-Output -InputObject (New-DynamicOption -Category $category -Name $script:Detailed -ExpectedType Switch -IsRequired $false) } Install { Write-Output -InputObject (New-DynamicOption -Category $category -Name $script:AcceptLicense -ExpectedType Switch -IsRequired $false) - Write-Output -InputObject (New-DynamicOption -Category $category -Name $script:Detailed -ExpectedType Switch -IsRequired $false) } } } diff --git a/src/public/Get-InstalledPackage.ps1 b/src/public/Get-InstalledPackage.ps1 index 71534a4..fd7da4a 100644 --- a/src/public/Get-InstalledPackage.ps1 +++ b/src/public/Get-InstalledPackage.ps1 @@ -27,9 +27,9 @@ function Get-InstalledPackage { $RequiredVersion = $(Find-WinGetPackage -Name $Name).Version } - # Convert the PSCustomObject output from Cobalt into PackageManagement SWIDs, then filter results by version requirements + # Convert the PSCustomObject output from Microsoft.WinGet.Client into PackageManagement SWIDs, then filter results by version requirements # This provides wildcard search behavior for locally installed packages, which WinGet lacks - Cobalt\Get-WinGetPackage | + Microsoft.WinGet.Client\Get-WinGetPackage | Where-Object {-Not $Name -Or ($_.ID -Like $Name)} | Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $RequiredVersion -MinimumVersion $MinimumVersion -MaximumVersion $MaximumVersion} | ConvertTo-SoftwareIdentity diff --git a/src/public/Install-Package.ps1 b/src/public/Install-Package.ps1 index 5b089ae..8c78f44 100644 --- a/src/public/Install-Package.ps1 +++ b/src/public/Install-Package.ps1 @@ -35,13 +35,8 @@ function Install-Package { Source = $Matches.source } - # Validate what WinGet installed matched what we requested, then convert the PSCustomObject output from Cobalt into PackageManagement SWIDs - $swid = Cobalt\Install-WinGetPackage @WinGetParams | Where-Object {Test-PackageVersion -Package $_ -RequiredVersion $WinGetParams.version -ErrorAction SilentlyContinue} | ConvertTo-SoftwareIdentity -Source $WinGetParams.Source + Install-WinGetPackage @WinGetParams - if (-Not $swid) { - # Cobalt returned something, but not in the format we expected. Something is amiss. - Write-Warning ($LocalizedData.UnexpectedWinGetResponse -f $FastPackageReference) - } - - $swid + #Microsoft.WinGet.Client doesn't return any package data on successful uninstallation, so we have to make up a new SWID to satisfy PackageManagement + ConvertTo-SoftwareIdentity -InputObject @($WinGetParams) } diff --git a/src/public/Remove-PackageSource.ps1 b/src/public/Remove-PackageSource.ps1 index e13639e..32fd65c 100644 --- a/src/public/Remove-PackageSource.ps1 +++ b/src/public/Remove-PackageSource.ps1 @@ -9,7 +9,7 @@ function Remove-PackageSource { Write-Debug ($LocalizedData.ProviderDebugMessage -f ('Remove-PackageSource')) - [array]$RegisteredPackageSources = Cobalt\Get-WinGetSource + [array]$RegisteredPackageSources = Microsoft.WinGet.Client\Get-WinGetSource # WinGet.exe will not error if the specified source name isn't already registered, so we will do it here instead. if (-not ($RegisteredPackageSources.Name -eq $Name)) { @@ -19,6 +19,6 @@ function Remove-PackageSource { -ErrorCategory InvalidArgument } - # Cobalt will throw an exception if unregistration fails - Cobalt\Unregister-WinGetSource -Name $Name + # Microsoft.WinGet.Client will throw an exception if unregistration fails + Microsoft.WinGet.Client\Remove-WinGetSource -Name $Name } diff --git a/src/public/Resolve-PackageSource.ps1 b/src/public/Resolve-PackageSource.ps1 index ca9ae6b..1247169 100644 --- a/src/public/Resolve-PackageSource.ps1 +++ b/src/public/Resolve-PackageSource.ps1 @@ -5,7 +5,7 @@ function Resolve-PackageSource { Write-Debug ($LocalizedData.ProviderDebugMessage -f ('Resolve-PackageSource')) # Get sources from WinGet - Cobalt\Get-WinGetSource | ForEach-Object { - New-PackageSource -Name $_.Name -Location $_.Arg -Trusted $true -Registered $true + Microsoft.WinGet.Client\Get-WinGetSource | ForEach-Object { + New-PackageSource -Name $_.Name -Location $_.Argument -Trusted $true -Registered $true } } diff --git a/src/public/Uninstall-Package.ps1 b/src/public/Uninstall-Package.ps1 index 066f05b..1cfab91 100644 --- a/src/public/Uninstall-Package.ps1 +++ b/src/public/Uninstall-Package.ps1 @@ -22,13 +22,12 @@ function Uninstall-Package { $WinGetParams = @{ ID = $Matches.name + Version = $Matches.version Source = $Matches.source } - Cobalt\Uninstall-WinGetPackage @WinGetParams + Microsoft.WinGet.Client\Uninstall-WinGetPackage @WinGetParams - # Cobalt doesn't return any output on successful uninstallation, so we have to make up a new SWID to satisfy PackageManagement - # Cobalt/WinGet doesn't take verion information on uninstall, but the SWID needs it - $WinGetParams.Version = $Matches.version + # Microsoft.WinGet.Client doesn't return any package data on successful uninstallation, so we have to make up a new SWID to satisfy PackageManagement ConvertTo-SoftwareIdentity -InputObject @($WinGetParams) }