O PowerShell é construído sobre o .NET Framework (ou .NET Core/.NET 5+), o que significa que você tem acesso a todas as classes, métodos e propriedades do .NET diretamente no seu terminal. Isso é uma das maiores vantagens do PowerShell: você não está limitado a cmdlets, mas pode usar toda a biblioteca de classes do .NET para manipular dados, arquivos, redes, sistemas e muito mais.

Nesta aula, vamos explorar como acessar essas classes .NET, como criar novos objetos a partir delas usando o cmdlet New-Object, como invocar métodos estáticos sem instanciar a classe, e vamos ver exemplos práticos que mostram o poder dessa integração.

Acessando classes .NET

No PowerShell, você pode acessar qualquer classe .NET pública usando seu nome completo (namespace + classe) entre colchetes. Por exemplo, para acessar a classe System.Math, você escreve [System.Math]. O namespace System é frequentemente omitido, pois é o namespace padrão, então [Math] também funciona.

Quando você referencia uma classe com colchetes, pode usar seus membros estáticos (métodos e propriedades que não exigem uma instância) diretamente. Para ver todos os membros estáticos disponíveis, você pode usar o cmdlet Get-Member com o parâmetro -Static.

# Acessando uma classe estática
[Math]::Pi
[Math]::Sqrt(16)

# Listando membros estáticos
[Math] | Get-Member -Static

Além de classes estáticas, você pode acessar classes que requerem instância. Por exemplo, System.DateTime representa uma data e hora, e você pode criar uma nova instância usando New-Object ou o operador :: para chamar construtores.

Para descobrir o namespace completo de uma classe, você pode usar o método FullName da própria classe ou consultar a documentação. O PowerShell também oferece atalhos para tipos comuns, como [int], [string], [bool], que são aliases para as classes .NET correspondentes.

New-Object

O cmdlet New-Object é usado para criar uma instância de uma classe .NET. Ele é equivalente ao operador new em outras linguagens. A sintaxe básica é New-Object -TypeName <NomeDaClasse> [-ArgumentList <Argumentos>].

Os argumentos são passados na ordem dos parâmetros do construtor. Por exemplo, para criar um objeto System.DateTime com uma data específica, você pode passar ano, mês e dia.

# Criando um objeto DateTime
$data = New-Object System.DateTime(2025, 3, 15)
$data

# Criando um objeto StringBuilder
$sb = New-Object System.Text.StringBuilder
$sb.Append("Olá, ") | Out-Null
$sb.Append("mundo!") | Out-Null
$sb.ToString()

Você também pode usar New-Object para criar objetos de coleções, como System.Collections.ArrayList, que é útil quando você precisa de uma lista dinâmica.

$lista = New-Object System.Collections.ArrayList
$lista.Add("Maçã")
$lista.Add("Banana")
$lista.Add("Laranja")
$lista

Se você precisar passar argumentos para o construtor, pode usar o parâmetro -ArgumentList ou simplesmente colocar os argumentos entre parênteses após o nome da classe, como no exemplo acima. O PowerShell interpreta isso como uma chamada de construtor.

Uma alternativa ao New-Object é usar o operador New-Object de forma implícita com a sintaxe [NomeDaClasse]::new(), que é mais concisa e semelhante ao C#.

$data = [DateTime]::new(2025, 3, 15)
$sb = [System.Text.StringBuilder]::new()

Métodos estáticos

Métodos estáticos são métodos que pertencem à classe em si, não a uma instância. Eles são chamados usando o operador :: após o nome da classe. Isso é útil para operações que não dependem do estado de um objeto específico.

Exemplos comuns incluem métodos de conversão, cálculos matemáticos, manipulação de strings, etc.

# Métodos estáticos de [Math]
[Math]::Max(10, 20)
[Math]::Round(3.14159, 2)

# Métodos estáticos de [String]
[string]::Join(", ", @("a", "b", "c"))
[string]::IsNullOrEmpty("texto")

# Métodos estáticos de [Environment]
[Environment]::UserName
[Environment]::GetFolderPath('Desktop')

Para descobrir quais métodos estáticos estão disponíveis, use Get-Member -Static na classe. Por exemplo, [Math] | Get-Member -Static lista todos os métodos e propriedades estáticas da classe System.Math.

Além disso, você pode combinar métodos estáticos com cmdlets para criar soluções poderosas. Por exemplo, para gerar um número aleatório, você pode usar a classe System.Random, que tem métodos de instância, ou a classe System.Guid que tem um método estático para gerar GUIDs.

# Gerando um GUID
$guid = [Guid]::NewGuid()
$guid.ToString()

# Número aleatório com Random
$rand = [Random]::new()
$rand.Next(1, 100)

Exemplos

Vamos colocar em prática com alguns exemplos que mostram como usar objetos .NET no dia a dia do PowerShell.

Exemplo 1: Trabalhando com datas

# Data atual
$hoje = [DateTime]::Now
$hoje.ToString("dd/MM/yyyy HH:mm:ss")

# Adicionando dias
$amanha = $hoje.AddDays(1)
$amanha.ToString("dd/MM/yyyy")

# Diferença entre datas
$dataInicio = [DateTime]::Parse("2025-01-01")
$diferenca = $hoje - $dataInicio
$diferenca.Days

Exemplo 2: Manipulação de strings com StringBuilder

$sb = [System.Text.StringBuilder]::new()
for ($i = 1; $i -le 10; $i++) {
    [void]$sb.Append("Linha $i`n")
}
$sb.ToString()

Exemplo 3: Usando coleções genéricas

# Lista genérica de inteiros
$numeros = [System.Collections.Generic.List[int]]::new()
$numeros.Add(1)
$numeros.Add(2)
$numeros.Add(3)
$numeros | ForEach-Object { $_ * 2 }

# Dicionário
$dicionario = [System.Collections.Generic.Dictionary[string, int]]::new()
$dicionario["um"] = 1
$dicionario["dois"] = 2
$dicionario["um"]

Exemplo 4: Acessando informações do sistema

# Informações do sistema operacional
$os = [System.Environment]::OSVersion
$os.VersionString

# Nome do computador
[System.Net.Dns]::GetHostName()

# Processadores
[System.Environment]::ProcessorCount

Exemplo 5: Lendo e escrevendo arquivos com .NET

# Escrevendo um arquivo
$caminho = "C:\temp\exemplo.txt"
[System.IO.File]::WriteAllText($caminho, "Conteúdo do arquivo")

# Lendo o arquivo
$conteudo = [System.IO.File]::ReadAllText($caminho)
$conteudo

# Verificando se existe
[System.IO.File]::Exists($caminho)

Esses exemplos mostram apenas a ponta do iceberg. O .NET oferece milhares de classes para praticamente qualquer tarefa, e o PowerShell permite usá-las de forma direta e eficiente.

Boas práticas e observações finais

Ao usar objetos .NET no PowerShell, lembre-se de que muitos cmdlets já fazem internamente o trabalho que você faria com .NET. Por exemplo, para ler um arquivo, você pode usar Get-Content, que é mais idiomático. Use .NET quando precisar de funcionalidades não disponíveis em cmdlets ou quando precisar de controle fino sobre o comportamento.

Além disso, ao usar New-Object, considere a alternativa ::new(), que é mais rápida e concisa. E sempre que possível, use os tipos acelerados como [int], [string], [datetime] para facilitar a leitura.

Por fim, explore a documentação do .NET para descobrir classes úteis. O site da Microsoft tem uma referência completa da API .NET, que é um recurso valioso.

Referências

Exercícios

  1. Crie um objeto System.DateTime representando a data do seu aniversário (use o ano atual) e exiba o dia da semana correspondente.

    ✓ Resposta:
    $aniversario = [DateTime]::new(2025, 3, 15) # Substitua pelo seu aniversário
    $aniversario.DayOfWeek
    
  2. Use New-Object para criar uma lista do tipo System.Collections.ArrayList, adicione três frutas e remova a segunda fruta da lista.

    ✓ Resposta:
    $lista = New-Object System.Collections.ArrayList
    $lista.Add("Maçã") | Out-Null
    $lista.Add("Banana") | Out-Null
    $lista.Add("Laranja") | Out-Null
    $lista.RemoveAt(1) # Remove o índice 1 ("Banana")
    $lista
    
  3. Invoque um método estático da classe [Math] para calcular a potência de 2 elevado a 10 e exiba o resultado.

    ✓ Resposta:
    [Math]::Pow(2, 10)
    
  4. Use a classe System.IO.File para escrever um texto em um arquivo chamado teste.txt no diretório atual e depois ler o conteúdo de volta.

    ✓ Resposta:
    $caminho = "$PWD\teste.txt"
    [System.IO.File]::WriteAllText($caminho, "Conteúdo de teste")
    [System.IO.File]::ReadAllText($caminho)
    
  5. Crie um objeto System.Random usando o construtor padrão e gere um número aleatório entre 1 e 100.

    ✓ Resposta:
    $rand = [Random]::new()
    $rand.Next(1, 101) # O limite superior é exclusivo, então 101 para incluir 100