A instrução switch no PowerShell é uma estrutura de controle que avalia uma expressão ou variável e executa blocos de código com base em condições de correspondência. Ela é mais legível e eficiente do que uma longa cadeia de if/elseif, especialmente quando você precisa comparar um valor com várias possibilidades. Diferente de outras linguagens, o switch do PowerShell é flexível: permite usar curingas, expressões regulares, processar coleções e até mesmo ler arquivos diretamente.

Nesta aula, você vai dominar a sintaxe básica, explorar as chaves -Wildcard e -Regex, entender como o PowerShell lida com múltiplas correspondências e aprender a usar o switch com arrays e arquivos. Ao final, terá exercícios para fixar o conteúdo e referências para aprofundamento.

Sintaxe

A sintaxe fundamental do switch é:

switch (expressão) { condição { bloco de código } ... default { bloco } }

A expressão é avaliada uma única vez e comparada com cada condição. Quando uma condição é verdadeira, o bloco correspondente é executado. A palavra-chave default é opcional e executa quando nenhuma condição é atendida. O operador de comparação padrão é -eq (igualdade), mas você pode alterar o comportamento com opções como -Wildcard ou -Regex.

Exemplo básico:

$fruta = 'banana'
switch ($fruta) {
    'maçã' { "$fruta é uma maçã." }
    'banana' { "$fruta é uma banana." }
    'laranja' { "$fruta é uma laranja." }
    default { "$fruta não é conhecida." }
}

Saída: banana é uma banana.

Você também pode usar condições mais complexas, como intervalos ou expressões:

$numero = 42
switch ($numero) {
    { $_ -lt 10 } { "Menor que 10" }
    { $_ -ge 10 -and $_ -lt 50 } { "Entre 10 e 49" }
    default { "50 ou mais" }
}

O bloco de script { $_ -lt 10 } é avaliado usando a variável automática $_ que representa o valor testado. Isso permite lógica personalizada.

-Wildcard e -Regex

Por padrão, o switch usa comparação exata (-eq). Para usar curingas ou expressões regulares, você adiciona as opções -Wildcard ou -Regex logo após a palavra switch.

-Wildcard: Permite usar padrões curinga (como * e ?) nas condições. Por exemplo:

$nome = 'João Silva'
switch -Wildcard ($nome) {
    'João*' { "Nome começa com João" }
    '*Silva' { "Nome termina com Silva" }
    '*o*' { "Nome contém a letra o" }
}

Neste caso, a primeira condição 'João*' será verdadeira, pois o nome começa com "João". As demais também seriam avaliadas (veja a próxima seção sobre múltiplas correspondências), mas a execução continua até o fim.

-Regex: Permite usar expressões regulares (regex) para correspondência de padrões complexos. Por exemplo:

$email = 'usuario@exemplo.com'
switch -Regex ($email) {
    '^[a-z]+@[a-z]+\.[a-z]{2,}$' { "E-mail válido" }
    default { "E-mail inválido" }
}

Lembre-se de escapar caracteres especiais em regex quando necessário. O PowerShell usa a sintaxe .NET regex.

Você também pode combinar -Wildcard e -Regex? Não diretamente, mas pode usar -Regex e dentro do bloco usar operadores curinga se precisar.

Múltiplas correspondências

Diferente de um if, o switch do PowerShell continua testando as condições mesmo depois de encontrar uma correspondência. Ou seja, ele executa todos os blocos cujas condições sejam verdadeiras, a menos que você use a instrução break para interromper. Isso é útil quando você quer processar múltiplos casos.

Exemplo:

$numero = 15
switch ($numero) {
    { $_ % 3 -eq 0 } { "Divisível por 3" }
    { $_ % 5 -eq 0 } { "Divisível por 5" }
    default { "Não é divisível por 3 nem 5" }
}

Saída: Divisível por 3 e Divisível por 5.

Para interromper após a primeira correspondência, use break:

$numero = 15
switch ($numero) {
    { $_ % 3 -eq 0 } { "Divisível por 3"; break }
    { $_ % 5 -eq 0 } { "Divisível por 5" }
    default { "Nenhum" }
}

Saída: apenas Divisível por 3.

A instrução continue também pode ser usada para pular para a próxima iteração quando você está processando uma coleção (veja a seção sobre arrays).

Arquivos e arrays

O switch pode processar uma coleção de itens, como um array ou o conteúdo de um arquivo, avaliando cada linha ou elemento. Para isso, você pode usar o parâmetro -File (para arquivos) ou simplesmente passar uma variável que contém um array.

Com arrays:

$frutas = @('maçã', 'banana', 'laranja', 'uva')
foreach ($fruta in $frutas) {
    switch ($fruta) {
        'maçã' { "Achei uma maçã!" }
        'banana' { "Achei uma banana!" }
        default { "$fruta não é maçã nem banana." }
    }
}

Mas o switch também pode receber o array diretamente:

$frutas = @('maçã', 'banana', 'laranja', 'uva')
switch ($frutas) {
    'maçã' { "Achei uma maçã!" }
    'banana' { "Achei uma banana!" }
    default { "$_ não é maçã nem banana." }
}

Nesse caso, cada elemento é testado. O default é executado para cada elemento que não corresponde a nenhuma condição.

Com arquivos: Use a opção -File para ler um arquivo linha por linha:

switch -File C:\dados\alunos.txt {
    '^[0-9]+' { "Linha começa com número: $_" }
    default { "Linha: $_" }
}

Cada linha do arquivo é passada como string para o switch, e você pode usar padrões regex ou curingas. Isso é muito útil para processar logs ou arquivos de configuração.

Boas práticas e observações finais

  • Use break se quiser apenas a primeira correspondência relevante.
  • Prefira switch em vez de múltiplos elseif para melhor legibilidade.
  • Combine switch com funções para criar pipelines de processamento.
  • Quando usar -Regex, teste suas expressões regularmente para evitar erros.
  • Em arquivos grandes, o switch -File pode ser mais eficiente que Get-Content + foreach.

Referências

Exercícios

  1. Exercício 1: Crie um script que use switch para classificar uma nota (0 a 10) como 'A' (9-10), 'B' (7-8), 'C' (5-6), 'D' (3-4) ou 'F' (0-2). Teste com vários valores.
  2. ✓ Resposta:
    function Get-Grade($nota) {
        switch ($nota) {
            { $_ -ge 9 } { "A" }
            { $_ -ge 7 } { "B" }
            { $_ -ge 5 } { "C" }
            { $_ -ge 3 } { "D" }
            default { "F" }
        }
    }
    Get-Grade 8.5  # B
  3. Exercício 2: Escreva um comando que use -Wildcard para verificar se um nome de arquivo termina com .txt, .log ou .ps1, e imprima uma mensagem específica para cada tipo.
  4. ✓ Resposta:
    $arquivo = "script.ps1"
    switch -Wildcard ($arquivo) {
        "*.txt" { "Arquivo de texto" }
        "*.log" { "Arquivo de log" }
        "*.ps1" { "Script PowerShell" }
        default { "Tipo desconhecido" }
    }
  5. Exercício 3: Use switch -Regex para validar se uma string é um endereço IP válido (formato x.x.x.x, cada parte entre 0 e 255). Dica: use regex e intervalos.
  6. ✓ Resposta:
    $ip = "192.168.0.1"
    switch -Regex ($ip) {
        "^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" {
            "IP válido"
        }
        default { "IP inválido" }
    }
  7. Exercício 4: Dado um array de números, use switch para imprimir se cada número é par, ímpar, ou negativo (priorize negativo). Exemplo: -3 → "Negativo", 4 → "Par", 7 → "Ímpar".
  8. ✓ Resposta:
    $numeros = -3, 4, 7, 0, -2
    foreach ($n in $numeros) {
        switch ($n) {
            { $_ -lt 0 } { "$_ é negativo" }
            { $_ % 2 -eq 0 } { "$_ é par" }
            default { "$_ é ímpar" }
        }
    }
  9. Exercício 5: Crie um arquivo de exemplo com várias linhas (ex.: nomes) e use switch -File para contar quantas linhas contêm a letra 'a' (case-insensitive).
  10. ✓ Resposta:
    $conteudo = @"
    Ana
    Bruno
    Carla
    Daniel
    "@
    $conteudo | Set-Content -Path "nomes.txt"
    $contador = 0
    switch -File "nomes.txt" {
        { $_ -match 'a' } { $contador++ }
    }
    "Total de linhas com 'a': $contador"