Как сказать PowerShell дождаться окончания каждой команды до начала следующего?

У меня есть PowerShell 1.0 script, чтобы просто открыть кучу приложений. Первая - это виртуальная машина, а другие - приложения для разработки. Я хочу, чтобы виртуальная машина завершила загрузку до открытия остальных приложений.

В bash я могу просто сказать "cmd1 && cmd2"

Это то, что у меня есть...

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

Ответ 1

Как правило, для внутренних команд PowerShell ждет перед началом следующей команды. Единственным исключением из этого правила является внешняя подсистема под управлением ОС Windows. Первый трюк состоит в том, чтобы выполнить конвейер до Out-Null следующим образом:

Notepad.exe | Out-Null

PowerShell будет ждать завершения процесса Notepad.exe перед продолжением. Это изящный, но тонкий, чтобы забрать от чтения код. Вы также можете использовать Start-Process с параметром -Wait:

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

Если вы используете версию расширения сообщества PowerShell, это:

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

Другой вариант в PowerShell 2.0 - использовать фоновое задание:

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

Ответ 2

Кроме того, используя Start-Process -Wait, конвейерный вывод исполняемого файла заставит Powershell ждать. В зависимости от необходимости я, как правило, подключаюсь к Out-Null, Out-Default, Out-String или Out-String -Stream. Здесь - длинный список некоторых других параметров вывода.

# 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

Мне не хватает операторов стиля CMD/Bash, на которые вы ссылались (&, & &, ||). Это Кажется, мы должны быть более подробно с Powershell.

Ответ 3

Просто используйте "Wait-process":

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

выполняется

Ответ 4

Если вы используете Start-Process <path to exe> -NoNewWindow -Wait

Вы также можете использовать опцию -PassThru для вывода эха.

Ответ 5

Некоторые программы не могут обрабатывать выходной поток очень хорошо, используя pipe to Out-Null, возможно, не заблокировать его.
И Start-Process нужен переключатель -ArgumentList для передачи аргументов, что не так удобно.
Существует и другой подход.

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

Ответ 6

Включение опции -NoNewWindow дает мне ошибку: Start-Process : This command cannot be executed due to the error: Access is denied.

Единственный способ заставить его работать:

Start-Process <path to exe> -Wait

Ответ 7

Принимая это дальше, вы можете даже разобрать на лету

например

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