How to tell PowerShell to wait for each command to end before starting the next?

PowershellWaitExecution

Powershell Problem Overview


I have a PowerShell 1.0 script to just open a bunch of applications. The first is a virtual machine and the others are development applications. I want the virtual machine to finish booting before the rest of the applications are opened.

In bash I could just say "cmd1 && cmd2"

This is what I've got...

C:\Applications\VirtualBox\vboxmanage startvm superdooper
    &"C:\Applications\NetBeans 6.5\bin\netbeans.exe"

Powershell Solutions


Solution 1 - Powershell

Normally, for internal commands PowerShell does wait before starting the next command. One exception to this rule is external Windows subsystem based EXE. The first trick is to pipeline to Out-Null like so:

Notepad.exe | Out-Null

PowerShell will wait until the Notepad.exe process has been exited before continuing. That is nifty but kind of subtle to pick up from reading the code. You can also use Start-Process with the -Wait parameter:

Start-Process <path to exe> -NoNewWindow -Wait

If you are using the PowerShell Community Extensions version it is:

$proc = Start-Process <path to exe> -NoNewWindow -PassThru
$proc.WaitForExit()

Another option in PowerShell 2.0 is to use a background job:

$job = Start-Job { invoke command here }
Wait-Job $job
Receive-Job $job

Solution 2 - Powershell

Besides using Start-Process -Wait, piping the output of an executable will make Powershell wait. Depending on the need, I will typically pipe to Out-Null, Out-Default, Out-String or Out-String -Stream. Here is a long list of some other output options.

# Saving output as a string to a variable.
$output = ping.exe example.com | Out-String

# Filtering the output.
ping stackoverflow.com | where { $_ -match '^reply' }

# Using Start-Process affords the most control.
Start-Process -Wait SomeExecutable.com

I do miss the CMD/Bash style operators that you referenced (&, &&, ||). It seems we have to be more verbose with Powershell.

Solution 3 - Powershell

Just use "Wait-process" :

"notepad","calc","wmplayer" | ForEach-Object {Start-Process $_} | Wait-Process ;dir

job is done

Solution 4 - Powershell

If you use Start-Process <path to exe> -NoNewWindow -Wait

You can also use the -PassThru option to echo output.

Solution 5 - Powershell

Some programs can't process output stream very well, using pipe to Out-Null may not block it.
And Start-Process needs the -ArgumentList switch to pass arguments, not so convenient.
There is also another approach.

$exitCode = [Diagnostics.Process]::Start(<process>,<arguments>).WaitForExit(<timeout>)

Solution 6 - Powershell

Including the option -NoNewWindow gives me an error: Start-Process : This command cannot be executed due to the error: Access is denied.

The only way I could get it to work was to call:

Start-Process <path to exe> -Wait

Solution 7 - Powershell

Taking it further you could even parse on the fly

e.g.

& "my.exe" | %{
    if ($_ -match 'OK')
    { Write-Host $_ -f Green }
    else if ($_ -match 'FAIL|ERROR')
    { Write-Host $_ -f Red }
    else 
    { Write-Host $_ }
}

Solution 8 - Powershell

There's always cmd.

cmd /c start /wait notepad

Or

notepad | out-host

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn MeeView Question on Stackoverflow
Solution 1 - PowershellKeith HillView Answer on Stackoverflow
Solution 2 - PowershellNathan HartleyView Answer on Stackoverflow
Solution 3 - PowershellFlaviofireView Answer on Stackoverflow
Solution 4 - PowershellSandy ChapmanView Answer on Stackoverflow
Solution 5 - PowershellifreeView Answer on Stackoverflow
Solution 6 - PowershelltwasbrilligView Answer on Stackoverflow
Solution 7 - PowershellJustinView Answer on Stackoverflow
Solution 8 - Powershelljs2010View Answer on Stackoverflow