From 1aacff42fa4ba6ca7cb171d227bb2f00ebb3f1d2 Mon Sep 17 00:00:00 2001 From: Victor Lyuboslavsky Date: Wed, 18 Sep 2024 10:30:33 -0500 Subject: [PATCH] Cherry-pick: Updated PS1 install/uninstall scripts to fail on error. (#22164) (#22203) (cherry-picked from commit ddbdce4ab91fde578850959ec90f73e380d99ef8) --- pkg/file/scripts/install_exe.ps1 | 7 +++++ pkg/file/scripts/install_msi.ps1 | 9 +++++- pkg/file/scripts/uninstall_exe.ps1 | 31 +++++++++++++++++++ .../testdata/scripts/install_exe.ps1.golden | 7 +++++ .../testdata/scripts/install_msi.ps1.golden | 9 +++++- .../testdata/scripts/uninstall_exe.ps1.golden | 31 +++++++++++++++++++ 6 files changed, 92 insertions(+), 2 deletions(-) diff --git a/pkg/file/scripts/install_exe.ps1 b/pkg/file/scripts/install_exe.ps1 index bdf858461df2..f4e83b4de3fd 100644 --- a/pkg/file/scripts/install_exe.ps1 +++ b/pkg/file/scripts/install_exe.ps1 @@ -3,6 +3,8 @@ $exeFilePath = "${env:INSTALLER_PATH}" +try { + # Add argument to install silently # Argument to make install silent depends on installer, # each installer might use different argument (usually it's "/S" or "/s") @@ -20,3 +22,8 @@ $exitCode = $process.ExitCode # Prints the exit code Write-Host "Install exit code: $exitCode" Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/scripts/install_msi.ps1 b/pkg/file/scripts/install_msi.ps1 index 838c431c1df1..fbd89aa10bc5 100644 --- a/pkg/file/scripts/install_msi.ps1 +++ b/pkg/file/scripts/install_msi.ps1 @@ -1,9 +1,16 @@ $logFile = "${env:TEMP}/fleet-install-software.log" +try { + $installProcess = Start-Process msiexec.exe ` -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 -exit $installProcess.ExitCode +Exit $installProcess.ExitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/scripts/uninstall_exe.ps1 b/pkg/file/scripts/uninstall_exe.ps1 index 31b53ea58097..bc6ea1421422 100644 --- a/pkg/file/scripts/uninstall_exe.ps1 +++ b/pkg/file/scripts/uninstall_exe.ps1 @@ -14,6 +14,11 @@ $machineKey = ` 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' $machineKey32on64 = ` 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + +$exitCode = 0 + +try { + [array]$uninstallKeys = Get-ChildItem ` -Path @($machineKey, $machineKey32on64) ` -ErrorAction SilentlyContinue | @@ -33,6 +38,24 @@ foreach ($key in $uninstallKeys) { $key.UninstallString } + # The uninstall command may contain command and args, like: + # "C:\Program Files\Software\uninstall.exe" --uninstall --silent + # Split the command and args + $splitArgs = $uninstallCommand.Split('"') + if ($splitArgs.Length -gt 1) { + if ($splitArgs.Length -eq 3) { + $uninstallArgs = "$( $splitArgs[2] ) $uninstallArgs".Trim() + } elseif ($splitArgs.Length -gt 3) { + Throw ` + "Uninstall command contains multiple quoted strings. " + + "Please update the uninstall script.`n" + + "Uninstall command: $uninstallCommand" + } + $uninstallCommand = $splitArgs[1] + } + Write-Host "Uninstall command: $uninstallCommand" + Write-Host "Uninstall args: $uninstallArgs" + $processOptions = @{ FilePath = $uninstallCommand PassThru = $true @@ -55,6 +78,14 @@ foreach ($key in $uninstallKeys) { if (-not $foundUninstaller) { Write-Host "Uninstaller for '$softwareName' not found." + # Change exit code to 0 if you don't want to fail if uninstaller is not + # found. This could happen if program was already uninstalled. $exitCode = 1 } + +} catch { + Write-Host "Error: $_" + $exitCode = 1 +} + Exit $exitCode diff --git a/pkg/file/testdata/scripts/install_exe.ps1.golden b/pkg/file/testdata/scripts/install_exe.ps1.golden index bdf858461df2..f4e83b4de3fd 100644 --- a/pkg/file/testdata/scripts/install_exe.ps1.golden +++ b/pkg/file/testdata/scripts/install_exe.ps1.golden @@ -3,6 +3,8 @@ $exeFilePath = "${env:INSTALLER_PATH}" +try { + # Add argument to install silently # Argument to make install silent depends on installer, # each installer might use different argument (usually it's "/S" or "/s") @@ -20,3 +22,8 @@ $exitCode = $process.ExitCode # Prints the exit code Write-Host "Install exit code: $exitCode" Exit $exitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/testdata/scripts/install_msi.ps1.golden b/pkg/file/testdata/scripts/install_msi.ps1.golden index 838c431c1df1..fbd89aa10bc5 100644 --- a/pkg/file/testdata/scripts/install_msi.ps1.golden +++ b/pkg/file/testdata/scripts/install_msi.ps1.golden @@ -1,9 +1,16 @@ $logFile = "${env:TEMP}/fleet-install-software.log" +try { + $installProcess = Start-Process msiexec.exe ` -ArgumentList "/quiet /norestart /lv ${logFile} /i `"${env:INSTALLER_PATH}`"" ` -PassThru -Verb RunAs -Wait Get-Content $logFile -Tail 500 -exit $installProcess.ExitCode +Exit $installProcess.ExitCode + +} catch { + Write-Host "Error: $_" + Exit 1 +} diff --git a/pkg/file/testdata/scripts/uninstall_exe.ps1.golden b/pkg/file/testdata/scripts/uninstall_exe.ps1.golden index 31b53ea58097..bc6ea1421422 100644 --- a/pkg/file/testdata/scripts/uninstall_exe.ps1.golden +++ b/pkg/file/testdata/scripts/uninstall_exe.ps1.golden @@ -14,6 +14,11 @@ $machineKey = ` 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*' $machineKey32on64 = ` 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*' + +$exitCode = 0 + +try { + [array]$uninstallKeys = Get-ChildItem ` -Path @($machineKey, $machineKey32on64) ` -ErrorAction SilentlyContinue | @@ -33,6 +38,24 @@ foreach ($key in $uninstallKeys) { $key.UninstallString } + # The uninstall command may contain command and args, like: + # "C:\Program Files\Software\uninstall.exe" --uninstall --silent + # Split the command and args + $splitArgs = $uninstallCommand.Split('"') + if ($splitArgs.Length -gt 1) { + if ($splitArgs.Length -eq 3) { + $uninstallArgs = "$( $splitArgs[2] ) $uninstallArgs".Trim() + } elseif ($splitArgs.Length -gt 3) { + Throw ` + "Uninstall command contains multiple quoted strings. " + + "Please update the uninstall script.`n" + + "Uninstall command: $uninstallCommand" + } + $uninstallCommand = $splitArgs[1] + } + Write-Host "Uninstall command: $uninstallCommand" + Write-Host "Uninstall args: $uninstallArgs" + $processOptions = @{ FilePath = $uninstallCommand PassThru = $true @@ -55,6 +78,14 @@ foreach ($key in $uninstallKeys) { if (-not $foundUninstaller) { Write-Host "Uninstaller for '$softwareName' not found." + # Change exit code to 0 if you don't want to fail if uninstaller is not + # found. This could happen if program was already uninstalled. $exitCode = 1 } + +} catch { + Write-Host "Error: $_" + $exitCode = 1 +} + Exit $exitCode