Uninstall and Install in same script?

I have an installer that requires uninstalling of its older version before installing the newer version (there’s no in-place upgrade option for it apparently).
Is the recommended approach to have two toolkits, one that uninstalls and requires apps be closed, and then a second one that runs the installer?
Just curious since I know the ‘proper’ way is to run this with either -action Install or -action Uninstall? Correct me if I’m wrong.

I prefer to handle previous versions uninstalls in the [Pre-Installation] phase of the Installer script, if no in-between reboot is required. If a reboot is required, then the dual script/deployment approach would make more sense.

To me, calling a script.ps1 -uninstall refers to the specific version this script installs, not its previous versions.

I do not claim this to be the ‘correct’ way as it depends on the use case and preferences, but this worked well for me. :slight_smile:

1 Like

Thanks and what about showing the install and closeapps window? This doesn’t appear to work and instead runs silent if I deploy from PDQ Deploy as a admin user to a computer where a standard user is logged onto.

I’ve just deployed an app in my environment with that same need. This is how I made it:

In my case, I had to close Outlook, but gave the user a time-out so they could save work. If no response, the script kills it AND if Outlook was not running, I still had to give them some warning that an installation was about to start.

So on the “Pre-Installation” phase:

Show-InstallationWelcome -CloseApps 'iexplore,outlook' -CloseAppsCountdown 300 -BlockExecution -AllowDefer -DeferTimes 3 -CheckDiskSpace -PersistPrompt -ForceCountDown 300

Now, for both these Countdowns to work without looping, I had to change some lines in the main script

Then I add a bit of code that searches for the old software in registry and removes it:

$uninstall32 = gci "HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "your_old_sw_name" } | select UninstallString
$uninstall64 = gci "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" | foreach { gp $_.PSPath } | ? { $_ -match "your_old_sw_name" } | select UninstallString

if ($uninstall64) {
$uninstall64 = $uninstall64.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall64 = $uninstall64.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall64 /qb" -Wait}
if ($uninstall32) {
$uninstall32 = $uninstall32.UninstallString -Replace "msiexec.exe","" -Replace "/I","" -Replace "/X",""
$uninstall32 = $uninstall32.Trim()
Write "Uninstalling..."
start-process "msiexec.exe" -arg "/X $uninstall32 /qb" -Wait}

From this point on, it’s just the standard script wonder: drop the new .msi file in “files” folder and let it install.

In my case I also needed a Count-Down and reboot at the end, so on the “Post-Installation” phase I’ve disabled the default message an add:

If (($mainExitCode -eq 0) -OR ($mainExitCode -eq 3010)) {
Show-InstallationRestartPrompt -Countdownseconds 300 -CountdownNoHideSeconds 60

Everybody was happy, no suprises and did the job.


1 Like