function Remove-WinUtilProvisionedAPPX { <# .SYNOPSIS Removes all AppX provisioned packages that match the given names .PARAMETER PackageList An array of names of the APPX packages to remove .EXAMPLE Remove-WinUtilProvisionedAPPX -PackageList @("Microsoft.Microsoft3DViewer", "Microsoft.WindowsCalculator") #> param ( [string[]]$PackageList ) if ($null -eq $PackageList -or $PackageList.Count -eq 0) { return } Write-Host "`nRemoving provisioned packages..." Write-WinUtilLog -Component "AppX" -Message "Removing AppX provisioned packages: $($PackageList -join ', ')" # DISM cmdlets like Get-AppxProvisionedPackage often fail with "Class not registered" or hang in PowerShell 7. # We shell out to Windows PowerShell 5.1 (powershell.exe) to reliably remove the provisioned packages. $ps5Command = { $pkgs = $args $provisionedPackages = Get-AppxProvisionedPackage -Online -ErrorAction SilentlyContinue $failures = [System.Collections.Generic.List[string]]::new() foreach ($Package in $pkgs) { $provs = $provisionedPackages | Where-Object DisplayName -Like "*$Package*" if ($null -ne $provs) { foreach ($prov in $provs) { try { Remove-AppxProvisionedPackage -Online -PackageName $prov.PackageName -ErrorAction Stop | Out-Null } catch { $failures.Add("Failed to remove provisioned AppX package $($prov.PackageName): $($_.Exception.Message)") } } } } if ($failures.Count -gt 0) { throw ($failures -join [Environment]::NewLine) } } $removalOutput = powershell.exe -NoProfile -NonInteractive -Command $ps5Command -args $PackageList 2>&1 if ($LASTEXITCODE -ne 0 -or $null -ne $removalOutput) { $failureDetails = ($removalOutput | Out-String).Trim() $errorMessage = "AppX provisioned package removal failed: $failureDetails" Write-WinUtilLog -Level "ERROR" -Component "AppX" -Message $errorMessage throw $errorMessage } Write-WinUtilLog -Component "AppX" -Message "AppX provisioned package removal completed." }