No PowerShell, erros são inevitáveis, mas a forma como você os trata pode determinar a robustez dos seus scripts. Nesta aula, exploraremos três mecanismos fundamentais para gerenciar erros: o parâmetro -ErrorAction (presente em cmdlets avançados), a variável de preferência $ErrorActionPreference (que define o comportamento padrão) e o parâmetro -ErrorVariable (que captura erros em uma variável). Compreender esses conceitos é essencial para escrever scripts previsíveis e resilientes.

O PowerShell classifica erros em duas categorias: terminantes (que interrompem a execução) e não terminantes (que permitem continuar). Os mecanismos desta aula atuam principalmente sobre erros não terminantes, que são os mais comuns em cmdlets como Get-ChildItem, Copy-Item ou Remove-Item.

-ErrorAction

O parâmetro -ErrorAction está disponível na maioria dos cmdlets avançados (que implementam [CmdletBinding()]). Ele permite especificar, no momento da chamada, como o cmdlet deve reagir a erros não terminantes. Os valores possíveis são:

  • Continue (padrão): exibe a mensagem de erro e continua a execução.
  • Stop: trata o erro como terminante, lançando uma exceção.
  • SilentlyContinue: suprime a mensagem de erro e continua.
  • Inquire: pergunta ao usuário o que fazer antes de cada erro.
  • Ignore: (PowerShell 3.0+) não registra o erro nem interrompe; não exibe mensagem.
  • Suspend: (fluxo de trabalho) suspende a execução.

Exemplo prático: suponha que você queira listar um arquivo que pode não existir, mas sem gerar mensagens de erro.

Get-Item -Path "C:\ArquivoInexistente.txt" -ErrorAction SilentlyContinue

O comando acima não exibirá erro. Se quiser que o erro interrompa o script (como uma exceção), use -ErrorAction Stop:

Get-Item -Path "C:\ArquivoInexistente.txt" -ErrorAction Stop

Isso lançará um erro terminante, que pode ser capturado com try/catch.

$ErrorActionPreference

A variável $ErrorActionPreference define o comportamento padrão para erros não terminantes em todo o escopo atual (script, função ou sessão). Ela aceita os mesmos valores que -ErrorAction, exceto Ignore (que não é suportado como preferência). O valor padrão é Continue.

Alterar essa variável afeta todos os cmdlets que não especificam explicitamente -ErrorAction. Por exemplo, para suprimir erros em todo um script:

$ErrorActionPreference = 'SilentlyContinue'
Get-Item "C:\Inexistente.txt"  # Nenhum erro exibido
Get-ChildItem "C:\OutroInexistente"  # Também sem erro

É uma boa prática restaurar o valor original após o uso, especialmente em scripts maiores, para não afetar outros comandos inesperadamente. Use try/finally ou salve o valor original:

$originalPref = $ErrorActionPreference
$ErrorActionPreference = 'Stop'
try {
    # comandos que devem parar no primeiro erro
} finally {
    $ErrorActionPreference = $originalPref
}

Lembre-se de que $ErrorActionPreference não afeta erros de sintaxe ou erros terminantes explícitos (como throw).

-ErrorVariable

O parâmetro -ErrorVariable permite capturar os erros não terminantes gerados por um cmdlet em uma variável específica, sem interromper a execução. A variável recebe uma lista de objetos ErrorRecord. É útil para inspecionar ou registrar erros posteriormente.

Sintaxe: -ErrorVariable NomeVariavel. Use + antes do nome para adicionar em vez de substituir.

Exemplo:

$erros = @()
Get-ChildItem -Path "C:\PastaInexistente" -ErrorVariable erros -ErrorAction SilentlyContinue
if ($erros) {
    Write-Host "Ocorreram $($erros.Count) erro(s):"
    $erros | ForEach-Object { $_.Exception.Message }
}

No exemplo, mesmo com -ErrorAction SilentlyContinue, os erros são capturados em $erros. Você pode então analisá-los sem interromper o fluxo.

Para adicionar erros a uma variável existente (sem substituir), use +:

$todosErros = @()
Get-ChildItem "C:\Pasta1" -ErrorVariable +todosErros -ErrorAction SilentlyContinue
Get-ChildItem "C:\Pasta2" -ErrorVariable +todosErros -ErrorAction SilentlyContinue

Isso acumula erros de múltiplos comandos.

Boas práticas

Ao lidar com erros no PowerShell, siga estas recomendações:

  • Prefira -ErrorAction Stop em operações críticas para que erros sejam tratados como exceções e possam ser capturados com try/catch. Isso torna o fluxo de erro explícito.
  • Use $ErrorActionPreference = 'Stop' no início de scripts que exigem que qualquer erro interrompa a execução, mas sempre restaure a preferência original ao final (use try/finally ou escopo local).
  • Evite SilentlyContinue sem capturar erros; se você suprime erros, pelo menos registre-os em log ou use -ErrorVariable para não perder informações de diagnóstico.
  • Não use $ErrorActionPreference = 'Ignore' (não é suportado como preferência); para ignorar erros, use o parâmetro -ErrorAction Ignore diretamente no cmdlet.
  • Documente o comportamento esperado em scripts compartilhados: indique qual política de erro está sendo usada.
  • Teste seus scripts com diferentes cenários de erro (arquivo ausente, permissão negada, etc.) para garantir que o tratamento de erros está correto.

Lembre-se: um script que lida bem com erros é mais confiável e fácil de depurar.

Referências

Exercícios

  1. Crie um comando que tente obter o item 'C:\Temp\nonexistent.txt' com -ErrorAction Stop e capture o erro em um bloco try/catch, exibindo a mensagem de erro.
  2. ✓ Resposta:
    try {
        Get-Item -Path "C:\Temp\nonexistent.txt" -ErrorAction Stop
    } catch {
        Write-Host "Erro capturado: $($_.Exception.Message)"
    }
    
  3. Altere a preferência de erro para SilentlyContinue e execute Get-ChildItem em uma pasta inexistente. Verifique que nenhum erro é exibido. Depois restaure a preferência.
  4. ✓ Resposta:
    $original = $ErrorActionPreference
    $ErrorActionPreference = 'SilentlyContinue'
    Get-ChildItem -Path "C:\PastaInexistente"
    $ErrorActionPreference = $original
    
  5. Use o parâmetro -ErrorVariable para capturar erros de Remove-Item ao tentar excluir um arquivo que não existe, sem exibir o erro na tela. Depois exiba a quantidade de erros.
  6. ✓ Resposta:
    $erros = @()
    Remove-Item -Path "C:\Temp\nonexistent.txt" -ErrorVariable erros -ErrorAction SilentlyContinue
    Write-Host "Quantidade de erros: $($erros.Count)"
    
  7. Escreva um script que liste o conteúdo de três pastas (C:\Folder1, C:\Folder2, C:\Folder3) e acumule todos os erros em uma única variável usando -ErrorVariable com +. Ao final, se houver erros, exiba a mensagem de cada um.
  8. ✓ Resposta:
    $todosErros = @()
    $pastas = @("C:\Folder1", "C:\Folder2", "C:\Folder3")
    foreach ($pasta in $pastas) {
        Get-ChildItem -Path $pasta -ErrorVariable +todosErros -ErrorAction SilentlyContinue
    }
    if ($todosErros) {
        foreach ($erro in $todosErros) {
            Write-Host $erro.Exception.Message
        }
    }
    
  9. Explique a diferença entre -ErrorAction Stop e $ErrorActionPreference = 'Stop' e dê um exemplo onde usar um é preferível ao outro.
  10. ✓ Resposta:

    -ErrorAction Stop é aplicado a um único comando, enquanto $ErrorActionPreference = 'Stop' afeta todos os comandos no escopo atual. Use -ErrorAction Stop quando apenas um comando específico deve gerar exceção (ex.: leitura de um arquivo de configuração). Use $ErrorActionPreference = 'Stop' quando todo o script deve parar ao primeiro erro (ex.: em uma sequência de operações dependentes). Exemplo: em um script que copia arquivos e depois os processa, se qualquer cópia falhar, o processamento não deve continuar; então defina $ErrorActionPreference = 'Stop' no início.