Pour comprendre pourquoi Start-Process et toutes ces autres commandes sont limitées, vous devez d’abord comprendre comment fonctionne un fichier EXE typique. Lorsqu’un fichier EXE est exécuté, il effectue l’action pour laquelle il a été conçu ; il envoie un ping quelque part (ping), lance un programme d’installation de logiciel (setup), recherche un enregistrement DNS (nslookup), etc. Pour cette partie et lancement de processus avec Start-Process a
insi que d’autres commandes fonctionnent très bien. C’est simple. La limitation survient lorsque cet EXE renvoie une sortie.
Nous pouvons démarrer un processus dans PowerShell de nombreuses manières différentes. Nous avons les cmdlets PowerShell Start-Process et Invoke-Expression
, nous pouvons appeler l’exécutable directement ou utiliser l’esperluette (&
) pour invoquer des expressions. La manière la plus courante est d’utiliser Start-Process
car c’est probablement la plus intuitive. PowerShell est connu pour son approche intuitive de la dénomination des commandes et Start-Process est un excellent choix. Cependant, cette commande est limitée.
Flux
Un fichier EXE comme de nombreux autres fichiers exécutables, sans se limiter à Windows, a un concept de flux standards. Les flux standards sont la façon dont les fichiers exécutables renvoient une sortie. Ces flux se présentent sous trois formes : stdin, stdout et stderr. Stdin est le flux qui peut être passé dans l’exécutable, sur lequel nous ne nous concentrerons pas ici. Stdout est le flux que l’exécutable utilise pour envoyer une sortie normale sans erreur.
En termes de PowerShell, considérez stdout comme ce que la commande « Write-Output » renvoie. Lorsqu’une erreur se produit (selon que le développeur de l’exécutable l’a écrit correctement), l’exécutable devrait renvoyer une sortie via stderr. Il s’agit d’un flux réservé au retour de toute information d’erreur.
Ces flux permettent aux utilisateurs de ces fichiers exécutables de différencier ce qui est une sortie normale de ce qui est une erreur. Les flux existent depuis des décennies et Windows ainsi que PowerShell les connaissent parfaitement et ont adopté les leurs.
Les codes de sortie
Un code de sortie, un code de retour ou un code de résultat est un autre concept ancien suivi par les fichiers exécutables. Un code de sortie est un entier qui permet à l’exécutable de signaler un état à l’utilisateur lorsqu’il se termine.
Il existe quelques codes de sortie standard que les programmes sont censés suivre, par exemple si le code de sortie est 0, tout va bien, le code de sortie 3010 signifie qu’un redémarrage est nécessaire, etc. PowerShell peut capturer ce code de sortie de différentes manières, par exemple en utilisant la variable automatique « $LastExitCode ». Les codes de sortie sont un autre moyen de communication de l’exécutable avec l’utilisateur.
Capturer les flux et les codes de sortie
Maintenant que vous comprenez ce avec quoi nous travaillons, utilisons un exemple. Pour simplifier, j’utiliserai le bon vieux ping.exe. Tout d’abord, je vais effectuer un ping sur google.com, ce qui renverra un résultat réussi. Nous n’utilisons pas ici la commande PowerShell « start process ».
I’ll now purposefully ping a host that doesn’t resolve a DNS name and will fail. Notice the value of $LastExitCode
.
Vous avez vu que le code de sortie diffère parce que le résultat de la commande ping était différent, mais vous n’avez pas vu les flux car nativement PowerShell ne comprend pas la différence lorsqu’il s’agit de fichiers exécutables. Le texte que vous voyez dans la console est blanc ; pas le texte d’erreur rouge que vous connaissez et aimez.
Nous pouvons capturer les flux et les rediriger vers des fichiers de différentes manières, comme l’utilisation de >
et 2>
comme ci-dessous. C’est la manière traditionnelle.
Remarquez cependant que, dans ce cas, même si ping.exe renvoie un code de sortie de 1 (comme indiqué ci-dessus), cette sortie va toujours vers stdout. C’est courant. Le flux et le code de sortie renvoyés dépendent entièrement du développeur et peuvent adopter de nombreuses formes différentes, malheureusement.
Si vous souhaitez adopter la méthode « moderne », vous pourriez utiliser Start-Process
et les paramètres -RedirectStandardError
et -RedirectStandardOutput
, mais ils seraient toujours redirigés vers des fichiers.
Limitations de Start-Process
Vous pouvez voir que démarrer un processus et renvoyer une sortie courante n’est pas trop courant. De plus, PowerShell ne gère pas très bien les flux et les codes de sortie. Si je devais utiliser Start-Process pour exécuter ping.exe
et que je voulais suivre ce qui s’est passé dans le résultat, je devrais faire quelque chose comme ça à chaque fois que je voulais exécuter un fichier exécutable.
I still wouldn’t get my error text either!
Fixons tout cela. Téléchargez une petite fonction que j’ai créée appelée Invoke-Process
depuis la Galerie PowerShell.
Maintenant, exécutez ping en utilisant un hôte valide et voyez ce qui se passe.

Bien remarquer comment nous obtenons la même sortie. C’est bien !
Maintenant, exécutez la commande ping en utilisant un hôte non valide.

Remarquez maintenant que nous obtenons le texte d’erreur rouge habituel, comme nous nous y attendrions si quelque chose avait mal tourné. Invoke-Process
utilise Start-Process
en interne pour capturer stdout, stderr et le code de sortie, puis envoie la sortie vers le flux approprié. C’est ainsi que cela devrait être !
Dommage que PowerShell n’ait pas facilité le travail avec les flux et les codes de sortie des fichiers exécutables, mais je suppose qu’aujourd’hui, nous pouvons l’ajouter maintenant qu’il est open source !