Enumerações, ou simplesmente enum, são um tipo de dado que define um conjunto de constantes nomeadas. No PowerShell, elas permitem criar um conjunto fixo de valores que uma variável pode assumir, tornando o código mais legível e menos propenso a erros. Em vez de usar números mágicos ou strings soltas, você pode usar nomes significativos que descrevem o valor.

Nesta aula, vamos explorar como declarar uma enumeração, definir seus valores (inclusive com números personalizados), e aplicá-la em situações reais, como parâmetros de funções, validação de entrada e comparações. Você verá que as enumerações são uma ferramenta poderosa para escrever scripts mais robustos e auto-documentados.

enum

No PowerShell, a palavra-chave enum é usada para declarar um novo tipo enumeração. A sintaxe básica é:

enum NomeDoTipo {
    Valor1
    Valor2
    Valor3
}

Cada item dentro das chaves é um membro da enumeração, e por padrão, eles recebem valores inteiros sequenciais começando em 0. O primeiro membro tem valor 0, o segundo 1, e assim por diante. Você pode usar a enumeração para declarar variáveis, parâmetros de função e até mesmo propriedades de classes.

Vamos criar uma enumeração simples para representar os dias da semana:

enum DiaDaSemana {
    Domingo
    Segunda
    Terca
    Quarta
    Quinta
    Sexta
    Sabado
}

Neste caso, Domingo vale 0, Segunda vale 1, e assim por diante. Para usar um valor, basta referenciá-lo como [DiaDaSemana]::Segunda.

Valores

Embora o padrão seja valores inteiros sequenciais, você pode atribuir valores explícitos a cada membro da enumeração. Isso é útil quando você precisa de códigos numéricos específicos, como códigos HTTP, ou quando deseja combinar valores como flags. A sintaxe permite atribuir um valor a cada membro:

enum StatusCode {
    Ok = 200
    Created = 201
    BadRequest = 400
    NotFound = 404
}

Se você não atribuir um valor a um membro, ele assume o valor do membro anterior + 1. Por exemplo:

enum Exemplo {
    A = 5
    B
    C = 10
    D
}

Nesse caso, B valerá 6 (pois A é 5 e B não tem valor explícito) e D valerá 11 (pois C é 10). É importante notar que os valores devem ser inteiros (int32), mas você pode usar qualquer número inteiro dentro do intervalo permitido.

Além disso, você pode converter entre o nome e o valor numérico usando casts. Por exemplo, [StatusCode]::Ok retorna o valor enumerado, e [int][StatusCode]::Ok retorna 200. Para converter um inteiro de volta para a enumeração, use [StatusCode]200 (disponível no PowerShell 5.0+).

Casos de uso

Enumerações são extremamente úteis em várias situações:

  • Parâmetros de função: Restringir os valores aceitos por um parâmetro a um conjunto definido, evitando entradas inválidas.
  • Validação de entrada: Comparar valores de forma mais legível, por exemplo, if ($status -eq [StatusCode]::NotFound).
  • Flags: Usar o atributo [Flags] para criar enumerações que podem ser combinadas com operadores bit a bit.
  • Legibilidade: Substituir números mágicos ou strings soltas por nomes que descrevem o significado.
  • Switch statements: Usar enums em blocos switch para tornar o código mais claro.

Por exemplo, ao criar um script que processa pedidos, você pode definir um enum para o status do pedido:

enum StatusPedido {
    Pendente
    Pago
    Enviado
    Entregue
    Cancelado
}

Assim, em vez de usar 0, 1, etc., você usa [StatusPedido]::Pago.

Exemplos

Vamos colocar em prática com exemplos mais completos.

Exemplo 1: Usando enum em uma função

function Get-StatusMessage {
    param(
        [StatusCode]$Code
    )
    switch ($Code) {
        ([StatusCode]::Ok) { "Tudo certo!" }
        ([StatusCode]::Created) { "Recurso criado." }
        ([StatusCode]::BadRequest) { "Requisição inválida." }
        ([StatusCode]::NotFound) { "Recurso não encontrado." }
        default { "Status desconhecido." }
    }
}

# Chamando a função
Get-StatusMessage -Code ([StatusCode]::NotFound)

Isso retorna "Recurso não encontrado.".

Exemplo 2: Enumeração como flags

[Flags()] enum Permissoes {
    Nenhuma = 0
    Leitura = 1
    Escrita = 2
    Execucao = 4
    Todas = Leitura -bor Escrita -bor Execucao
}

# Combinando permissões
$perm = [Permissoes]::Leitura -bor [Permissoes]::Escrita

# Verificando se uma permissão está presente
if ($perm -band [Permissoes]::Escrita) {
    "Tem permissão de escrita."
}

No exemplo, Permissoes usa o atributo [Flags] e valores em potências de 2, permitindo combinações.

Exemplo 3: Convertendo valores

# Obtendo o valor inteiro de um membro
[int][StatusCode]::Created  # retorna 201

# Convertendo inteiro para enum
[StatusCode]404  # retorna NotFound

# Listando todos os membros de uma enumeração
[Enum]::GetNames([StatusCode])

Essas conversões são úteis ao interagir com APIs ou quando você precisa armazenar valores em formato numérico.

Exemplo 4: Validação em parâmetros avançados

function Set-LogLevel {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [ValidateSet('Info', 'Warn', 'Error')]
        [string]$Level
    )
    # ...
}

# Mas com enum, você pode fazer:
enum LogLevel {
    Info
    Warn
    Error
}

function Set-LogLevel {
    param(
        [Parameter(Mandatory)]
        [LogLevel]$Level
    )
    Write-Host "Nível definido para $Level"
}

Com enum, o parâmetro só aceita valores válidos, e o autocompletar no console mostra os nomes.

Boas práticas

  • Use nomes em PascalCase para os tipos e membros da enumeração.
  • Se os valores precisam ser armazenados ou transmitidos, prefira atribuir valores explícitos para evitar quebras se a ordem mudar.
  • Para combinações, use o atributo [Flags] e valores que sejam potências de 2.
  • Evite usar enums para conjuntos que podem crescer indefinidamente; prefira classes ou validação dinâmica.
  • Documente os significados de cada membro, especialmente se os valores numéricos forem significativos.

Referências

Exercícios

  1. Exercício 1: Crie uma enumeração chamada Prioridade com os valores Baixa, Media, Alta e Urgente. Atribua valores inteiros 1, 2, 3 e 4 respectivamente. Mostre como obter o valor inteiro de 'Alta'.

    ✓ Resposta:
    enum Prioridade {
        Baixa = 1
        Media = 2
        Alta = 3
        Urgente = 4
    }
    
    [int][Prioridade]::Alta  # retorna 3
  2. Exercício 2: Escreva uma função chamada Get-FruitColor que aceita um enum Fruta com membros Manca (Manga), Banana, Uva e retorna a cor correspondente (laranja, amarelo, roxo). Use um switch.

    ✓ Resposta:
    enum Fruta {
        Manga
        Banana
        Uva
    }
    
    function Get-FruitColor {
        param([Fruta]$Fruta)
        switch ($Fruta) {
            ([Fruta]::Manga) { "Laranja" }
            ([Fruta]::Banana) { "Amarelo" }
            ([Fruta]::Uva) { "Roxo" }
        }
    }
    
    Get-FruitColor -Fruta ([Fruta]::Banana)  # retorna "Amarelo"
  3. Exercício 3: Crie uma enumeração DiaSemana com os dias de segunda a sexta. Depois, escreva um script que itere sobre todos os valores e imprima cada um com seu valor inteiro.

    ✓ Resposta:
    enum DiaSemana {
        Segunda
        Terca
        Quarta
        Quinta
        Sexta
    }
    
    foreach ($dia in [Enum]::GetValues([DiaSemana])) {
        "$dia = $([int]$dia)"
    }
  4. Exercício 4: Defina uma enumeração NivelAcesso com valores Leitura, Escrita, Exclusao. Crie uma função que recebe um nível e retorna uma string descrevendo o que o usuário pode fazer. Use if/elseif.

    ✓ Resposta:
    enum NivelAcesso {
        Leitura
        Escrita
        Exclusao
    }
    
    function Get-AccessDescription {
        param([NivelAcesso]$Nivel)
        if ($Nivel -eq [NivelAcesso]::Leitura) {
            "Pode apenas ler."
        } elseif ($Nivel -eq [NivelAcesso]::Escrita) {
            "Pode ler e escrever."
        } elseif ($Nivel -eq [NivelAcesso]::Exclusao) {
            "Pode ler, escrever e excluir."
        }
    }
    
    Get-AccessDescription -Nivel ([NivelAcesso]::Escrita)
  5. Exercício 5: Crie uma enumeração com o atributo [Flags] chamada PermissoesArquivo com Leitura (1), Escrita (2), Execucao (4). Inicialize uma variável com Leitura e Escrita, depois verifique se Execucao está presente e imprima o resultado.

    ✓ Resposta:
    [Flags()] enum PermissoesArquivo {
        Leitura = 1
        Escrita = 2
        Execucao = 4
    }
    
    $perm = [PermissoesArquivo]::Leitura -bor [PermissoesArquivo]::Escrita
    
    if ($perm -band [PermissoesArquivo]::Execucao) {
        "Tem permissão de execução."
    } else {
        "Não tem permissão de execução."
    }