HOWTO · PowerShell
Como encerrar um script no Windows PowerShell
Saiba quando usar exit, return, throw, break, continue ou Stop-Process para encerrar o escopo correto e retornar um código de saída confiável no PowerShell.
Nesta página
Encerrar um script do PowerShell não é uma única operação. A instrução correta depende do que precisa parar: todo o processo do script, apenas a função atual, uma iteração ou outro processo do sistema operacional.
| Objetivo | Instrução |
|---|---|
| Finalizar o script principal e informar um status | exit <código> |
| Sair de uma função, script ou bloco de script | return |
| Informar uma falha que o chamador possa capturar | throw |
Sair de um loop ou switch |
break |
Avançar para o próximo item do loop ou switch |
continue |
| Encerrar outro processo local | Stop-Process |
Encerrar um script do PowerShell com exit
exit encerra um script ou uma instância do PowerShell. Um inteiro opcional se torna o código de saída do processo: por convenção, 0 indica sucesso e um valor diferente de zero indica falha. Documente cada código de erro para que tarefas agendadas, trabalhos de CI e programas chamadores possam reagir corretamente.
Salve este script de entrada como Check-Config.ps1:
param([Parameter(Mandatory)][string]$Path)
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
Write-Error "Configuration file not found: $Path"
exit 2
}
Write-Output 'Configuration file found.'
exit 0
Execute-o como processo filho em outra sessão do PowerShell e consulte o status:
powershell.exe -NoProfile -File .\Check-Config.ps1 -Path .\missing.json
$LASTEXITCODE
O último comando exibe 2. No PowerShell 7, use pwsh no lugar de powershell.exe. O chamador PowerShell lê o status do processo filho em $LASTEXITCODE; no cmd.exe, o valor fica em %ERRORLEVEL%.
Reserve exit para o limite do script principal. Se uma função reutilizável chamar exit, ela poderá fechar uma sessão interativa, um executor de testes ou outro host. Prefira funções que retornem dados ou gerem erros e deixe somente o script de entrada converter o resultado em um código de saída.
Sair do escopo atual com return
return sai da função, do script ou do bloco de script atual. A instrução não define, por si só, um código de saída do processo.
function Get-ConfigText {
param([string]$Path)
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
return $null
}
Get-Content -LiteralPath $Path -Raw
}
Em uma função comum do PowerShell, todo valor não capturado do fluxo de sucesso faz parte da saída, e não apenas a expressão após return. Para diagnósticos, use Write-Verbose ou outro fluxo apropriado em vez de emitir strings extras com Write-Output.
Parar com um erro capturável usando throw
throw cria, por padrão, um erro que encerra o script e desenrola a pilha de chamadas até que um bloco catch ou uma instrução trap o trate. Use-o quando uma função não puder produzir um resultado válido e o chamador tiver de decidir como se recuperar.
function Get-RequiredConfig {
param([string]$Path)
if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) {
throw "Configuration file not found: $Path"
}
Get-Content -LiteralPath $Path -Raw
}
try {
$config = Get-RequiredConfig -Path '.\settings.json'
}
catch {
Write-Error $_
exit 2
}
O padrão separa responsabilidades: a função descreve a falha com throw, enquanto o script de entrada a captura e escolhe o código público. Nem todo erro de cmdlet chega automaticamente a catch; acrescente -ErrorAction Stop a um erro não terminante quando ele precisar ser tratado ali.
Usar break e continue somente em blocos de controle
break sai do loop ou switch mais próximo. continue ignora o restante da iteração atual e inicia a seguinte.
foreach ($name in 'alpha', '', 'beta', 'stop', 'omega') {
if ([string]::IsNullOrWhiteSpace($name)) {
continue
}
if ($name -eq 'stop') {
break
}
Write-Output $name
}
Saída:
alpha
beta
Essas palavras-chave não são comandos genéricos para encerrar scripts. Fora de um loop, switch ou trap, o PowerShell pode procurar uma construção delimitadora na pilha de chamadas e encerrar o runspace atual se não encontrar nenhuma.
Encerrar outro processo com Stop-Process
Stop-Process atua em um processo separado no computador local; ele não significa “parar este script”. Visualize primeiro uma correspondência ampla com -WhatIf:
Get-Process -Name notepad -ErrorAction SilentlyContinue |
Stop-Process -WhatIf
Remova -WhatIf somente depois de confirmar os alvos. Prefira um objeto de processo conhecido ou um PID quando um nome puder corresponder a vários processos. Encerrar o processo de outro usuário também pode exigir uma sessão elevada do PowerShell.
Preservar códigos de saída de programas nativos
$? informa se o último comando do PowerShell foi bem-sucedido, enquanto $LASTEXITCODE armazena o código de saída do último programa nativo. Salve o valor imediatamente, pois outro comando nativo pode sobrescrevê-lo.
git status --porcelain
$gitCode = $LASTEXITCODE
if ($gitCode -ne 0) {
Write-Error "git failed with exit code $gitCode"
exit $gitCode
}
Use return ou throw na lógica reutilizável e reserve exit <código> para o limite do script principal. Assim, a saída das funções, o fluxo de controle e o status do processo permanecem distintos e previsíveis.
Preservar a limpeza e distinguir o cancelamento
Mantenha a limpeza em finally, e não após uma linha que possa encerrar o processamento. Segundo a documentação das palavras-chave do PowerShell, finally é executado se o trabalho em try tiver sucesso, se um erro alcançar catch, se exit for chamado ou se Ctrl+C interromper o script; use-o para liberar um fluxo, bloqueio ou arquivo temporário.
$stream = $null
try {
$stream = [System.IO.File]::OpenRead($Path)
# Process the stream.
}
finally {
if ($null -ne $stream) {
$stream.Dispose()
}
}
Deixe o código reutilizável fazer throw ou return até o script de entrada, para que limpeza e status sejam escolhidos em um local visível. Ctrl+C, um trabalho interrompido e uma entrada inválida são eventos diferentes: decida e documente se cada um é cancelamento, falha de validação ou outro status ao qual chamador ou agendador devem reagir. Não os reduza silenciosamente a uma falha genérica. Encerrar outro processo é diferente; prefira o desligamento normal do aplicativo. Stop-Process -Force pode impedir a limpeza de arquivos ou estado e só deve ser usado quando essa consequência for entendida.
Manter scripts filhos e hosts no escopo pretendido
O operador de chamada executa um script filho no seu próprio escopo; dot-sourcing o executa no escopo atual e importa suas funções e variáveis. Use dot-sourcing apenas quando importar definições for intencional.
# Run the child in its own script scope.
& .\Child.ps1
# Import definitions into the current scope.
. .\Functions.ps1
Um exit em código reutilizável pode fechar uma sessão interativa, executor de testes ou outro host. Um filho iniciado com powershell.exe -File ou pwsh -File devolve o controle ao chamador; um console interativo pode encerrar sua sessão. Runspaces incorporados e editores podem agir de modo diferente. Teste a linha de comando real, incluindo -File versus -Command, perfis, aspas, saída e status separadamente.
Recomendação
Reserve exit <código> ao limite superior, return ao escopo atual, throw a uma falha que o chamador possa tratar, break e continue ao respectivo loop ou switch, e Stop-Process a um processo local separado. Funções que retornam dados ou lançam erros continuam reutilizáveis; um pequeno script de entrada pode traduzir o resultado para shell, agendador, CI ou wrapper.