Hashtables são estruturas de dados fundamentais no PowerShell, permitindo armazenar pares de chave e valor de forma eficiente. Diferentemente de arrays, que indexam por números, hashtables usam chaves únicas (geralmente strings) para acessar rapidamente os valores. Esta aula cobre desde a criação até casos de uso avançados, com exemplos práticos para o dia a dia do administrador de sistemas.

Criação

Para criar uma hashtable, use a sintaxe @{}. As chaves e valores são separados por ponto e vírgula ou quebra de linha. As chaves são strings, mas podem ser outros tipos. Exemplo básico:

$hash = @{ Nome = 'João'; Idade = 30; Cidade = 'São Paulo' }

Também é possível criar uma hashtable vazia e adicionar elementos posteriormente:

$hash = @{}
$hash['Nome'] = 'Maria'
$hash.Idade = 25

Note que você pode acessar e atribuir valores usando colchetes ou notação de ponto (propriedade). A notação de ponto só funciona para chaves que são strings válidas como nomes de propriedade (sem espaços ou caracteres especiais).

Acesso por chave

Para acessar um valor, use a chave entre colchetes ou a notação de ponto. Se a chave não existir, retorna $null (com colchetes) ou erro (com ponto). Exemplo:

$hash = @{ Nome = 'João'; Idade = 30 }
Write-Host $hash['Nome']  # João
Write-Host $hash.Idade    # 30
# Acessando chave inexistente:
Write-Host $hash['Peso']  # $null
# Write-Host $hash.Peso   # Erro!

Para verificar se uma chave existe, use ContainsKey() ou teste com $null:

if ($hash.ContainsKey('Nome')) { 'Existe' } else { 'Não existe' }

Iteração

Iterar sobre uma hashtable pode ser feito de várias formas. O método mais comum é usar GetEnumerator() para obter pares chave-valor:

$hash = @{ A = 1; B = 2; C = 3 }
foreach ($par in $hash.GetEnumerator()) {
    Write-Host "Chave: $($par.Key), Valor: $($par.Value)"
}

Você também pode iterar apenas sobre as chaves ou valores:

foreach ($chave in $hash.Keys) { Write-Host $chave }
foreach ($valor in $hash.Values) { Write-Host $valor }

Outra forma é usar o método ForEach() (PowerShell 4+):

$hash.GetEnumerator() | ForEach-Object { Write-Host "$($_.Key): $($_.Value)" }

Casos de uso

Hashtables são extremamente versáteis. Aqui estão alguns casos comuns:

  • Mapeamento de configurações: Armazenar parâmetros de script de forma legível.
  • Cache de resultados: Evitar recálculos armazenando resultados de operações caras.
  • Estruturas de dados aninhadas: Hashtables dentro de hashtables para representar objetos complexos.
  • Conversão de objetos: Transformar hashtables em objetos PSObject para saída formatada.

Exemplo de hashtable aninhada:

$config = @{
    Servidor = 'srv01'
    Portas = @{ HTTP = 80; HTTPS = 443 }
}
Write-Host $config.Portas.HTTP  # 80

Outro exemplo: usar hashtable para selecionar ações com base em uma chave:

$acoes = @{
    start  = { Start-Service -Name 'Spooler' }
    stop   = { Stop-Service -Name 'Spooler' }
    status = { Get-Service -Name 'Spooler' }
}
$acao = 'status'
& $acoes[$acao]

Boas práticas

  • Use chaves consistentes (todas minúsculas ou maiúsculas) para evitar confusão com case-sensitivity (PowerShell é case-insensitive, mas a chave original é preservada).
  • Evite usar chaves com espaços ou caracteres especiais se for usar notação de ponto; prefira colchetes.
  • Para hashtables grandes, considere usar [ordered] se precisar preservar a ordem de inserção (a partir do PowerShell 3.0): $hash = [ordered]@{ ... }.
  • Sempre verifique a existência da chave antes de acessar com notação de ponto para evitar erros.

Referências

Exercícios

  1. Crie uma hashtable chamada $pessoa com as chaves Nome, Idade e Cidade, e preencha com seus dados. Depois exiba o valor de Idade.

    ✓ Resposta:
    $pessoa = @{ Nome = 'SeuNome'; Idade = 30; Cidade = 'SuaCidade' }
    Write-Host $pessoa['Idade']  # ou $pessoa.Idade
  2. Adicione uma nova chave 'Profissao' à hashtable do exercício anterior e depois remova a chave 'Cidade'. Exiba a hashtable final.

    ✓ Resposta:
    $pessoa['Profissao'] = 'Analista'
    $pessoa.Remove('Cidade')
    $pessoa  # exibe a hashtable
  3. Itere sobre uma hashtable com chaves 'A', 'B', 'C' e valores 1,2,3 e exiba cada par no formato 'Chave: Valor'.

    ✓ Resposta:
    $hash = @{ A = 1; B = 2; C = 3 }
    foreach ($par in $hash.GetEnumerator()) {
        Write-Host "$($par.Key): $($par.Value)"
    }
  4. Crie uma hashtable aninhada que represente um computador, com chaves 'Nome' (string) e 'SO' (outra hashtable com chaves 'Nome' e 'Versao'). Exiba a versão do SO.

    ✓ Resposta:
    $computador = @{
        Nome = 'PC01'
        SO = @{ Nome = 'Windows'; Versao = '10' }
    }
    Write-Host $computador.SO.Versao
  5. Use uma hashtable para mapear nomes de serviços a ações (Start, Stop, Restart). Crie uma hashtable com chaves 'Spooler' e 'WSearch' e valores (scriptblocks que executem o respectivo comando). Em seguida, execute a ação 'Start' para o serviço 'Spooler'.

    ✓ Resposta:
    $acoes = @{
        Start   = { Start-Service -Name $args[0] }
        Stop    = { Stop-Service -Name $args[0] }
        Restart = { Restart-Service -Name $args[0] }
    }
    $servico = 'Spooler'
    & $acoes['Start'] $servico