From 923e9804414ad8490d058f145c63d65e798c9a5b Mon Sep 17 00:00:00 2001 From: David Obando Date: Thu, 8 May 2025 13:28:25 -0700 Subject: [PATCH] Increase reliability of winget task This change adds a second try to install packages or apply configurations when Invoke-CimMethod doesn't work. This can happen in certain scenarios (for example, when machine policies reduce the context of what Invoke-CimMethod can do for security reasons), leading to user frustration. This change is an attempt to help make the winget task more likely to succeed installing packages in user context (not system) by doing a second attempt to run the installation or application command but using Start-Process instead of Invoke-CimMethod. --- Tasks/git-clone/main.ps1 | 19 ++++++++++++++++--- Tasks/winget/main.ps1 | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/Tasks/git-clone/main.ps1 b/Tasks/git-clone/main.ps1 index f506c24..f928feb 100644 --- a/Tasks/git-clone/main.ps1 +++ b/Tasks/git-clone/main.ps1 @@ -308,9 +308,22 @@ function InstallPackage{ $process.WaitForExit() $installExitCode = $process.ExitCode if ($installExitCode -ne 0) { - Write-Error "Failed to install $PackageId with Install-WinGetPackage, error code $($installExitCode)." - # this was the last try, so exit with the install exit code - exit $installExitCode + if ($PsInstallScope -eq "CurrentUser") { + # try executing the commandlet via Start-Process instead of using Invoke-CimMethod, as this works better in some cases + $process = Start-Process -FilePath "C:\Program Files\PowerShell\7\pwsh.exe" -ArgumentList "-Command $($installPackageCommand)" -PassThru + $handle = $process.Handle # cache process.Handle so ExitCode isn't null when we need it below + $process.WaitForExit() + $installExitCode = $process.ExitCode + if ($installExitCode -ne 0) { + Write-Error "Failed to install package. Exit code: $($installExitCode)." + exit $installExitCode + } + } + else { + Write-Error "Failed to install $PackageId with Install-WinGetPackage, error code $($installExitCode)." + # this was the last try, so exit with the install exit code + exit $installExitCode + } } # read the output file and write it to the console diff --git a/Tasks/winget/main.ps1 b/Tasks/winget/main.ps1 index 066c0d1..78c6b20 100644 --- a/Tasks/winget/main.ps1 +++ b/Tasks/winget/main.ps1 @@ -385,8 +385,21 @@ else { $process.WaitForExit() $installExitCode = $process.ExitCode if ($installExitCode -ne 0) { - Write-Error "Failed to install package. Exit code: $($installExitCode)." - exit 1 + if ($PsInstallScope -eq "CurrentUser") { + # try executing the commandlet via Start-Process instead of using Invoke-CimMethod, as this works better in some cases + $process = Start-Process -FilePath "C:\Program Files\PowerShell\7\pwsh.exe" -ArgumentList "-Command $($installPackageCommand)" -PassThru + $handle = $process.Handle # cache process.Handle so ExitCode isn't null when we need it below + $process.WaitForExit() + $installExitCode = $process.ExitCode + if ($installExitCode -ne 0) { + Write-Error "Failed to install package. Exit code: $($installExitCode)." + exit 2 + } + } + else { + Write-Error "Failed to install package. Exit code: $($installExitCode)." + exit 1 + } } # read the output file and write it to the console @@ -430,8 +443,21 @@ else { $process.WaitForExit() $installExitCode = $process.ExitCode if ($installExitCode -ne 0) { - Write-Error "Failed to run configuration file installation. Exit code: $($installExitCode)." - exit 1 + if ($PsInstallScope -eq "CurrentUser") { + # try executing the commandlet via Start-Process instead of using Invoke-CimMethod, as this works better in some cases + $process = Start-Process -FilePath "C:\Program Files\PowerShell\7\pwsh.exe" -ArgumentList "-Command $($applyConfigCommand)" -PassThru + $handle = $process.Handle # cache process.Handle so ExitCode isn't null when we need it below + $process.WaitForExit() + $installExitCode = $process.ExitCode + if ($installExitCode -ne 0) { + Write-Error "Failed to run configuration file installation. Exit code: $($installExitCode)." + exit 2 + } + } + else { + Write-Error "Failed to run configuration file installation. Exit code: $($installExitCode)." + exit 1 + } } # read the output file and write it to the console