web-dev-qa-db-fra.com

Comment dire à PowerShell d'attendre la fin de chaque commande avant de commencer la suivante?

J'ai un script PowerShell 1.0 pour ouvrir tout un tas d'applications. Le premier est une machine virtuelle et les autres sont des applications de développement. Je souhaite que la machine virtuelle termine le démarrage avant que le reste des applications ne soit ouvert.

En bash je pourrais juste dire "cmd1 && cmd2"

C'est ce que j'ai.

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

Normalement, pour les commandes internes, PowerShell attend avant de lancer la commande suivante. Une exception à cette règle concerne les fichiers EXE externes basés sur un sous-système Windows. La première astuce consiste à créer un pipeline vers Out-Null comme suit:

Notepad.exe | Out-Null

PowerShell attendra la fin du processus Notepad.exe avant de continuer. C'est astucieux mais assez subtil à lire après avoir lu le code. Vous pouvez également utiliser Start-Process avec le paramètre -Wait:

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

Si vous utilisez la version des extensions de communauté PowerShell, celle-ci est:

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

Une autre option de PowerShell 2.0 consiste à utiliser un travail d’arrière-plan:

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

Outre l'utilisation de Start-Process -Wait, le fait de canaliser la sortie d'un fichier exécutable fera attendre Powershell. En fonction des besoins, je dirigerai généralement vers Out-Null, Out-Default, Out-String ou Out-String -Stream. Here est une longue liste de quelques autres options de sortie. 

# 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

Les opérateurs de style CMD/Bash auxquels vous avez fait référence (&, &&, ||) me manquent. Il semble que nous devions être plus verbeux avec Powershell .

42
Nathan Hartley

Il suffit d'utiliser "Wait-process":

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

la tâche est finie

11
Flaviofire

Certains programmes ne traitent pas très bien le flux de sortie. L'utilisation de la fonction pipe to Out-Null peut ne pas le bloquer.
Et Start-Process a besoin du commutateur -ArgumentList pour passer des arguments, ce qui n’est pas très pratique.
Il y a aussi une autre approche. 

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

Si vous utilisez Start-Process <path to exe> -NoNewWindow -Wait

Vous pouvez également utiliser l'option -PassThru pour faire écho à la sortie.

5
Sandy Chapman

Y compris l'option -NoNewWindow me donne une erreur: Start-Process : This command cannot be executed due to the error: Access is denied.

La seule façon de le faire fonctionner était d'appeler:

Start-Process <path to exe> -Wait
2
twasbrillig

En allant plus loin, vous pouvez même analyser à la volée

par exemple.

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