How to Restart After Running EXE Installer

I am completely new to PowerShell… As in I just started using it a few days ago. Much patience will be greatly appreciated…
Most of our workstations are Windows 7, so I am writing and testing the script using PowerShell ISE 2.0

I am attempting to write a script that will automate the installation of an application. Before doing so, I want the script to check for previous versions, if there are any, uninstall those version, wait for the uninstaller to finish, and reboot the computer. The part I am struggling with is how to get the script to reboot the computer ONLY if the uninstaller runs. Below is what I am attempting to use to accomplish this.

if (([bool] ($version)-eq $true)-and(($version)-ne $ActVer)) {Invoke-Expression “\Server\Folder\Uninstall.exe /silent” | Start-Sleep -s 20} Restart-Computer

There are several other parameters that are needed but, currently don’t work… That is a separate issue though.

I have asked Google several times…
I have tried -Wait
I have tried Out-Null
Finally, I tried Start-Sleep

The only time anything works is when I put Restart-Computer outside the { }. Unfortunately, this caused the computer to reboot regardless of whether or not the uninstaller runs.

Have you tried Start-Process with the Wait parameter?

Something like this:

Start-Process -FilePath  "\\Server\Folder\Uninstall.exe" -ArgumentList '/sleep' -Wait

PowerShell will then check if the process is still running, and when it isn’t it will go to the next line in the script, which in this case is the computer restart.


Well, two things.

If you only want Restart-Computer to run after your uninstaller runs, then Restart-Computer should probably be INSIDE the If{} construct, not outside it.

if (([bool] ($version)-eq $true)-and(($version)-ne $ActVer)) {
  Invoke-Expression "\\Server\Folder\Uninstall.exe /silent"
  Start-Sleep -s 20

Which isn’t how you have it.

But you might look into Start-Process, instead. That will return a System.Diagnostics.Process object, and you can check to see that it’s still running. Or, don’t wrap in Invoke-Expression - just run the uninstaller directly. That should also give you an exit code when the thing finishes, and then you can go on and do whatever.

Thank you for the replies.

Alexander - I tried -Wait but it didn’t work. From the looks of it, that cmdlet was not introduced until PowerShell 3.0. I am doing this in v2.0 since all of our workstations are running Windows 7. I read a little bit about the Start-Process command, but haven’t tried it yet.

Don - I had previously tried putting Restart-Computer in the { } in the following format and it didn’t work.

if (([bool] ($version)-eq $true)-and(($version)-ne $ActVer)) {Invoke-Expression “\Server\Folder\Uninstall.exe /silent” | Start-Sleep -s 20 Restart-Computer}

I just changed it to read exactly as you recommended and that worked perfectly! Thanks! I have since changed it to the following because I didn’t like defining a specific wait time before the reboot. I don’t want the wait time to be too short or too long.

if (([bool] ($version)-eq $true)-and(($version)-ne $ActVer)) {
$Job = Start-Job {Invoke-Expression “\Server\Folder\Uninstall.exe /silent”}
Wait-Job $Job
Receive-Job $Job

Thanks for getting me pointed in a better direction!

Trying to cram all of this into a one-liner is part of what’s making it harder for you.

if (([bool] ($version)-eq $true)-and(($version)-ne $ActVer)) {Invoke-Expression "\\Server\Folder\Uninstall.exe /silent" ; Start-Sleep -s 20 ; Restart-Computer}

Notice the semicolon used to separate two commands when you aren’t using a carriage return to do so. I don’t think the pipe was actually appropriate there, either.

if (([bool] ($version)-eq $true)-and(($version)-ne $ActVer)) {
 Invoke-Expression "\\Server\Folder\Uninstall.exe /silent" 
 Start-Sleep -s 20 

Would also have worked. Just so it’s here for posterity ;). Glad you got it going.

Hi again!

The -Wait parameter for the Start-Process cmdlet exists in PowerShell v2.