各コマンドの終了を待ってから次のコマンドを開始するようにPowerShellに指示する方法は?


211

たくさんのアプリケーションを開くだけのPowerShell 1.0スクリプトがあります。1つは仮想マシンで、他は開発アプリケーションです。残りのアプリケーションを開く前に、仮想マシンの起動を終了したいのですが。

バッシュでは私はただ言うことができます "cmd1 && cmd2"

これは私が持っているものです...

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

回答:


366

通常、内部コマンドの場合、PowerShellは次のコマンドを開始する前に待機します。このルールの1つの例外は、外部WindowsサブシステムベースのEXEです。最初のトリックは、次のOut-Nullようにパイプライン処理することです。

Notepad.exe | Out-Null

PowerShellは、Notepad.exeプロセスが終了するまで待機してから続行します。それは気の利いたものですが、コードを読むことから拾うのはちょっと微妙です。Start-Processを-Waitパラメーターと共に使用することもできます。

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

PowerShell Community Extensionsバージョンを使用している場合:

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

PowerShell 2.0のもう1つのオプションは、バックグラウンドジョブを使用することです。

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

2
私の悪い。Start-Process -Waitはうまく動作しますが、今はこれが私が探していたものではないことがわかりました...実際には、vmが起動を完了するまで待つことを求めています。大変になると思います。そのための新しいスレッドを見つける必要があると思います。ありがとう。
John Mee

7
すばらしい、| out-null私が必要とするものだけをしました。使用してみましたStart-Jobが、関数の結果をパラメーターとして渡しているため、少しスキッツォイドが表示され、最後の提案を使用できませんでした...
jcolebrand

6
補足として、複数の引数を-ArgumentListで渡す必要がある場合は、のようにコンマで区切ります-ArgumentList /D=test,/S
sschuberth

1
単純な "<path to exe> | Out-Null"ソリューションをありがとう!「Start-Process <exeへのパス> -NoNewWindow -Wait」メソッドの問題は、親がその前に終了した場合でも、親によって生成されたすべての子プロセスが完了するまでPowerShellが一時停止することです。これにより、セットアッププログラムの問題が発生しました。
zax

これは、VMが起動するのを待つために使用するStart-AzureRmVM -ResourceGroupName $ ResourceGroupName -Name $ VmName while((Get-AzureRmVM -ResourceGroupName $ ResourceGroupName -Name $ VmName -Status | `select -ExpandProperty Statuses |`?{$ _.Code -match "PowerState"} | `select -ExpandProperty DisplayStatus)-ne" VM running "){Start-Sleep -s 2} Start-Sleep -s 5 ## VMが起動できるようにして、VMが受け入れられるようにしますリモートリクエスト
andrewmo 2018

47

の使用Start-Process -Waitに加えて、実行可能ファイルの出力をパイプすると、Powershellが待機します。必要に応じて、私は通常、パイプへの意志Out-NullOut-DefaultOut-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ではもっと冗長にする必要があるようです。


出力を解析する必要がある場合、これは非常に優れたソリューションです。
Jan Rothkegel

コンソール出力を保持する必要があるため、Out-xxxxリダイレクタリストを指摘することで、なぜOut-NullではなくOut-Defaultを使用する必要があるのか​​がすぐにわかりました。
Julio Nobre、

注意まったく余計な作業が実行するのに必要ではありませんコンソール同期アプリケーションを-任意のシェルのように、それはデフォルトの動作です。パイピングOut-String は出力単一の複数行の文字列に変更しますが、PowerShellはデフォルトで行の配列を返します。Start-Process(本当に新しいウィンドウで実行したい場合を除いて)コンソールアプリケーションでは、出力をキャプチャしたりリダイレクトしたりすることはできないため、避けてください。
mklement0

実際、ネイティブコマンドが同期的に(出力を使用して)実行されるか、非同期的に実行されるかは、実行可能ファイルに依存します。例として、出力をキャプチャせずに、以下は "bingo"のみを出力します。& 'C:\ Program Files \ Mozilla Firefox \ firefox.exe'-?; 「ビンゴ」
ネイサンハートレイ

12

「待機プロセス」を使用するだけです:

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

仕事は終わりました


8

使用する場合 Start-Process <path to exe> -NoNewWindow -Wait

-PassThruオプションを使用して出力をエコーすることもできます。


出力を-PassThruエコーしないことに注意してください(非コンソールアプリケーションは、コンソール出力を生成しません)。新しく起動されたプロセスを表すインスタンスを出力するため、そのプロパティを調べて、後で終了するのを待つことができます。System.Diagnostics.Process
mklement0

6

一部のプログラムは出力ストリームをうまく処理できず、パイプを使用してOut-Nullブロックしない場合があります。
そして、Start-Process必要が-ArgumentListないので便利、引数を渡すようにスイッチを。
別のアプローチもあります。

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

1
その呼び出しで複数の引数がどのように機能しますか?彼らはどのように区切られていますか?ネストされたさまざまな文字列のエスケープをどのように処理しますか?ty!
AnneTheAgile、2015年

1
@AnneTheAgile doc はスペースを使用して引数を区切り、charエスケープはバックスラッシュを使用
ifree

ty @ifree、そのように実行するためにtestcompleteを取得しました!スペース区切りの引数のリストを単一引用符で囲みました。[1]; しかし、ここで$ exitcode = falseをエコーし​​ます。これは、プロセスからの戻りコードではありませんでしたか?[1] $ exitCode = [Diagnostics.Process] :: Start( "c:\ Program Files(x86)\ SmartBear \ TestComplete 10 \ Bin \ TestComplete.exe"、 '"c:\ Users \ ME \ Documents \ TestComplete 10 Projects \ hig4TestProject1 \ hig4TestProject1.pjs "/ run / project:myProj / test:" KeywordTests | zTdd1_Good "/ exit ').WaitForExit(60)
AnneTheAgile

3

オプション-NoNewWindowを含めるとエラーが発生します。Start-Process : This command cannot be executed due to the error: Access is denied.

私がそれを機能させる唯一の方法は、呼び出すことでした:

Start-Process <path to exe> -Wait

0

さらに進んで、その場で解析することもできます

例えば

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

0

常にcmdがあります。start-processへの引数の引用に問題がある場合は、それほど煩わしくないかもしれません。

cmd /c start /wait notepad
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.