PuTTY
About
PuTTY is a free and open-source terminal emulator, serial console and network file transfer application. It supports several network protocols, including SCP, SSH, Telnet, rlogin, and raw socket connection. It can also connect to a serial port.
Version 0.74.0.0
PuTTY is now available as a MSI installer, but previously was an executable. This means to script the removal of any version we need to mitigate for each possibility. There are particular requirements for the EXE removal, oddly that putty.exe must be deleted before the uninstall starts in order to make it silent.
Assumptions
This document assumes you are familiar with the use of a Windows Administrator Command Prompt. It also assumes your copy of the PSADT is preconfigured to write logs to C:\ProgramData\Logs.
Obtain Package Source
PuTTY is freely available for download.
Deploy Info
PuTTY release 0.74 Simon Tatham C:\Program Files (x86)\PuTTY\putty.exe Hive: HKEY_LOCAL_MACHINE Key: SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{8F276E88-8C75-43AF-A245-7112AE5AF2DA} Value: DisplayVersion DataType: Version Data: 0.74.0.0 Operator: Greater than or equal to 32-bit: No SCCM Requirement: None
Deploy-Application.ps1
Please note the script contains Pre-installation logic to detect and uninstall any legacy version it encounters and logs the version number. Removes any version of PuTTY, whether 32 or 64-bit. A variable array is used to ensure both Program Files locations are checked. A variable is also used to determine the name of the uninstaller executable (used in older versions), as this can vary between unins000.exe and unins001.exe, depending upon how many times the software has been previously installed and removed.
Relevant extracts from the script are as follows:
##*=============================================== ##* VARIABLE DECLARATION ##*=============================================== ## Variables: Application [string]$appVendor = 'Simon Tatham' [string]$appName = 'PuTTY' [string]$appVersion = '0.74' [string]$appArch = 'x64' [string]$appLang = 'EN' [string]$appRevision = '01' [string]$appScriptVersion = '1.0.0' [string]$appScriptDate = '17/11/2020' [string]$appScriptAuthor = 'psadt.com' [string]$Parms = "/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-" [string]$nameSearch = "*PuTTY*" ##*=============================================== ##*=============================================== ##* PRE-INSTALLATION ##*=============================================== [string]$installPhase = 'Pre-Installation' ## Show Welcome Message, close Internet Explorer if required, allow up to 3 deferrals, verify there is enough disk space to complete the install, and persist the prompt # Show-InstallationWelcome -CloseApps 'iexplore' -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt ## Show Progress Message (with the default message) # Show-InstallationProgress ## <Perform Pre-Installation tasks here> # Remove previous versions if exist Write-Log -Message "Check for and uninstall previous versions of PuTTY (32 or 64-bit)" -LogType 'CMTrace' # EXE Uninstall # This is run before the MSI uninstall only if the uninstall file exists [array]$appFolders = ${env:ProgramFiles(x86)},$env:ProgramFiles ForEach ($appFolder in $appFolders) { $appPath = $appFolder + '\' + $appName # This file is checked solely to log the versions found before removal If (Test-Path "$appPath\putty.exe") {$OldVersion = (Get-Item "$appPath\putty.exe").VersionInfo.FileVersion} # EXE uninstall filename ends in a variable number which must be checked $UninstEXE = 'unins*.exe' $Uninst = dir -Path $appPath -Filter $UninstEXE -Force -ErrorAction SilentlyContinue | %{$_.FullName} If ($Uninst -ne $null) { $appExist = 1 ForEach ($UninstFile in $Uninst) { Write-Log -Message "$appName EXE installation detected." -LogType 'CMTrace' Write-Log -Message "Uninstalling $appName $OldVersion" -LogType 'CMTrace' Write-Log -Message "Executing $UninstFile $Parms" -LogType 'CMTrace' Remove-Item "$appPath\putty.exe" Start-Process $UninstFile -ArgumentList $Parms -Wait -PassThru -NoNewWindow -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null Sleep 5 Remove-Item $appPath -Recurse -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } } } If ($appExist -ne 1) {Write-Log -Message "No $appName EXE installations detected." -LogType 'CMTrace'} # MSI Uninstall $UninstMSI = Get-WmiObject -Class win32_product | where { $_.Name -like $nameSearch} If ($UninstMSI -ne $null) { ForEach ($app in $UninstMSI) { Write-Log -Message "$appName MSI installation detected." -LogType 'CMTrace' Write-Log -Message "Uninstalling $appName $($app.Version)" -LogType 'CMTrace' Write-Log -Message "MsiExec.exe /x $($app.IdentifyingNumber) /qn REBOOT=R /l*v `"$env:ProgramData\Logs\$pkgName $($app.Version) MSI Uninstall.log`"" -LogType 'CMTrace' Start-Process -FilePath MsiExec.exe -ArgumentList "/x $($app.IdentifyingNumber) /qn REBOOT=R /l*v `"$env:ProgramData\Logs\$pkgName $($app.Version) MSI Uninstall.log`"" -Wait -PassThru -NoNewWindow -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null } } Else {Write-Log -Message "No $appName MSI installations detected." -LogType 'CMTrace'} ##*=============================================== ##* INSTALLATION ##*=============================================== [string]$installPhase = 'Installation' <## Handle Zero-Config MSI Installations If ($useDefaultMsi) { [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Install'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) } Execute-MSI @ExecuteDefaultMSISplat; If ($defaultMspFiles) { $defaultMspFiles | ForEach-Object { Execute-MSI -Action 'Patch' -Path $_ } } } #> ## <Perform Installation tasks here> Execute-MSI -Action 'Install' -Path 'putty-0.74-installer.msi' -PassThru -ContinueOnError $false ##*=============================================== ##* UNINSTALLATION ##*=============================================== [string]$installPhase = 'Uninstallation' ## Handle Zero-Config MSI Uninstallations If ($useDefaultMsi) { [hashtable]$ExecuteDefaultMSISplat = @{ Action = 'Uninstall'; Path = $defaultMsiFile }; If ($defaultMstFile) { $ExecuteDefaultMSISplat.Add('Transform', $defaultMstFile) } Execute-MSI @ExecuteDefaultMSISplat } # <Perform Uninstallation tasks here> # Remove any version if exist Write-Log -Message "Check for and uninstall previous versions of PuTTY (32 or 64-bit)" -LogType 'CMTrace' # EXE Uninstall # This is run before the MSI uninstall only if the uninstall file exists [array]$appFolders = ${env:ProgramFiles(x86)},$env:ProgramFiles ForEach ($appFolder in $appFolders) { $appPath = $appFolder + '\' + $appName # This file is checked solely to log the versions found before removal If (Test-Path "$appPath\putty.exe") {$OldVersion = (Get-Item "$appPath\putty.exe").VersionInfo.FileVersion} # EXE uninstall filename ends in a variable number which must be checked $UninstEXE = 'unins*.exe' $Uninst = dir -Path $appPath -Filter $UninstEXE -Force -ErrorAction SilentlyContinue | %{$_.FullName} If ($Uninst -ne $null) { $appExist = 1 ForEach ($UninstFile in $Uninst) { Write-Log -Message "$appName EXE installation detected." -LogType 'CMTrace' Write-Log -Message "Uninstalling $appName $OldVersion" -LogType 'CMTrace' Write-Log -Message "Executing $UninstFile $Parms" -LogType 'CMTrace' Remove-Item "$appPath\putty.exe" Start-Process $UninstFile -ArgumentList $Parms -Wait -PassThru -NoNewWindow -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null Sleep 5 Remove-Item $appPath -Recurse -Force -ErrorAction SilentlyContinue -WarningAction SilentlyContinue } } } If ($appExist -ne 1) {Write-Log -Message "No $appName EXE installations detected." -LogType 'CMTrace'} # MSI Uninstall $UninstMSI = Get-WmiObject -Class win32_product | where { $_.Name -like $nameSearch} If ($UninstMSI -ne $null) { ForEach ($app in $UninstMSI) { Write-Log -Message "$appName MSI installation detected." -LogType 'CMTrace' Write-Log -Message "Uninstalling $appName $($app.Version)" -LogType 'CMTrace' Write-Log -Message "MsiExec.exe /x $($app.IdentifyingNumber) /qn REBOOT=R /l*v `"$env:ProgramData\Logs\$pkgName $($app.Version) MSI Uninstall.log`"" -LogType 'CMTrace' Start-Process -FilePath MsiExec.exe -ArgumentList "/x $($app.IdentifyingNumber) /qn REBOOT=R /l*v `"$env:ProgramData\Logs\$pkgName $($app.Version) MSI Uninstall.log`"" -Wait -PassThru -NoNewWindow -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | Out-Null } } Else {Write-Log -Message "No $appName MSI installations detected." -LogType 'CMTrace'}