Para entender por que o Start-Process e todos esses outros comandos são limitados, primeiro você tem que entender como um arquivo EXE típico funciona. Quando um arquivo EXE é executado, ele realiza qualquer ação para a qual foi projetado; ele faz ping em algo (ping), inicia um instalador de software (setup), procura algum registro DNS (nslookup), o que quer que seja. Para esta parte e Start-Process a
nd outros comandos para iniciar um processo funcionam muito bem. É simples. A limitação ocorre quando esse EXE retorna alguma saída.
Podemos iniciar um processo no PowerShell de várias maneiras diferentes. Temos os cmdlets Start-Process do PowerShell e Invoke-Expression
, podemos chamar o executável diretamente ou usar o símbolo de e comercial (&
) para invocar expressões. A maneira mais comum é usar Start-Process
porque é provavelmente a mais intuitiva. O PowerShell é conhecido por sua abordagem intuitiva para nomeação de comandos e Start-Process é uma excelente escolha. No entanto, esse comando é limitado.
Streams
Um arquivo EXE, como muitos outros arquivos executáveis, não se limita ao Windows e tem um conceito de fluxos padrão. Fluxos padrão são como os arquivos executáveis retornam saída. Esses fluxos vêm em três sabores: stdin, stdout e stderr. Stdin é o fluxo que pode ser passado para o executável, sobre o qual não nos concentraremos aqui. Stdout é o fluxo que o executável usa para enviar saída normal, sem erros.
Em termos do PowerShell, pense em stdout como o que o Write-Output
retorna. Quando ocorre um erro (dependendo se o desenvolvedor do executável o escreveu corretamente), o executável deve retornar saída via stderr. Esta é uma stream que é reservada para retornar qualquer informação de erro.
Essas streams permitem que os usuários desses arquivos executáveis diferenciem entre o que é uma saída típica e o que é um erro. As streams existem há décadas e, portanto, o Windows e o PowerShell sabem tudo sobre elas e adotaram as suas próprias.
Códigos de Saída
Um código de saída, código de retorno ou código de resultado é outro conceito antigo que os arquivos executáveis também seguem. Um código de saída é um inteiro que permite ao executável sinalizar um status para o usuário quando ele sai.
Há alguns códigos de saída padrão que os programas são supostos a seguir, como se o código de saída for 0, tudo está bem, o código de saída 3010 significa que precisa de uma reinicialização e assim por diante. O PowerShell pode capturar esse código de saída de algumas maneiras diferentes, como usando a variável automática $LastExitCode
. Códigos de saída são outro método pelo qual o arquivo executável comunica ao usuário.
Capturando Streams e Códigos de Saída
Agora que você entende o que estamos trabalhando, vamos usar um exemplo. Para manter simples, vou usar o bom e velho ping.exe. Primeiro, vou pingar o google.com, o que retornará um resultado bem-sucedido. Não estamos usando o start process do PowerShell aqui.
I’ll now purposefully ping a host that doesn’t resolve a DNS name and will fail. Notice the value of $LastExitCode
.
Você viu que o código de saída difere porque o resultado do ping foi diferente, mas você não viu os fluxos porque nativamente o PowerShell não entende a diferença quando se trata de arquivos executáveis. O texto que você vê no console é branco; não é o texto de erro vermelho que você conhece e ama.
Podemos capturar os fluxos e redirecionar para arquivos de algumas maneiras diferentes, como usando >
e 2>
como abaixo. Este é o modo antigo.
Observe, no entanto, que, neste caso, mesmo que ping.exe esteja retornando um código de saída 1 (como mostrado acima), essa saída ainda será enviada para stdout. Isso é comum. Qual fluxo e código de saída são retornados é completamente escolha do desenvolvedor e vem em muitos estilos diferentes, infelizmente.
Se você quiser seguir o caminho “novo”, poderia usar Start-Process
e usar os parâmetros -RedirectStandardError
e -RedirectStandardOutput
, mas eles ainda seriam enviados apenas para arquivos.
Limitações do Start-Process
Você pode ver que iniciar um processo e retornar alguma saída comum não é tão comum. Além disso, o PowerShell não lida muito bem com os fluxos e códigos de saída. Se eu fosse usar Start-process para executar ping.exe
e quisesse acompanhar o que aconteceu no resultado, teria que fazer algo assim sempre que quisesse executar um arquivo executável.
I still wouldn’t get my error text either!
Vamos corrigir tudo isso. Baixe uma pequena função que criei chamada Invoke-Process
da PowerShell Gallery.
Agora execute ping usando um host válido e veja o que acontece.

Repare como obtemos a mesma saída. Isso é bom!
Agora execute ping usando um host inválido.

Agora repare que obtemos o texto de erro vermelho típico como esperávamos se algo desse errado. Invoke-Process
usa Start-Process
por baixo dos panos para capturar stdout, stderr e o código de saída e depois envia a saída para qualquer fluxo para onde deveria ir. É assim que deveria ser!
É uma pena que o PowerShell não tenha facilitado o trabalho com fluxos e códigos de saída de arquivos executáveis, mas eu suponho que hoje em dia, podemos adicionar isso lá agora que é de código aberto!