Bem-vindo à aula 7 do nosso curso de PowerShell. Até agora, você já usou cmdlets como Get-Process e Get-Service, e viu saídas formatadas em tabelas ou listas. Mas por baixo dos panos, o PowerShell não trabalha com texto — ele trabalha com objetos. Essa é a diferença mais importante entre o PowerShell e shells tradicionais como CMD ou Bash. Nesta aula, vamos mergulhar nesse conceito e mostrar como ele transforma a maneira como você automatiza tarefas.

Quando você executa um comando no PowerShell, o resultado não é uma sequência de caracteres, mas sim um ou mais objetos .NET. Cada objeto tem um tipo específico, propriedades (dados) e métodos (ações). Isso permite que você manipule dados de forma estruturada, sem precisar fazer parsing de texto — uma fonte comum de erros em scripts tradicionais.

Objetos vs texto

Em shells baseadas em texto, como o CMD do Windows ou o Bash no Linux, a saída dos comandos é puro texto. Por exemplo, ao executar dir no CMD, você vê uma lista formatada de arquivos, mas para extrair o nome de um arquivo específico, você precisa usar ferramentas como findstr ou awk para fazer parsing. Isso é frágil: se o formato da saída mudar (por exemplo, em outro idioma), seu script quebra.

No PowerShell, cada comando retorna objetos. O cmdlet Get-ChildItem (equivalente ao dir) retorna objetos do tipo System.IO.FileInfo ou System.IO.DirectoryInfo. Esses objetos têm propriedades como Name, Length, LastWriteTime, e métodos como Delete(). Você pode acessá-los diretamente sem se preocupar com a formatação da tela. Por exemplo:

# Obter o primeiro arquivo do diretório atual
$arquivo = Get-ChildItem -File | Select-Object -First 1
# Exibir o nome e o tamanho em KB
"Nome: $($arquivo.Name), Tamanho: $($arquivo.Length / 1KB) KB"

Isso é muito mais robusto e legível do que tentar extrair essas informações de uma string.

Propriedades e métodos

Objetos no PowerShell têm propriedades (atributos que descrevem o objeto) e métodos (ações que o objeto pode executar). Por exemplo, um objeto System.Diagnostics.Process (retornado por Get-Process) tem propriedades como Id, ProcessName, CPU, e métodos como Kill() e WaitForExit().

Você pode acessar uma propriedade usando a notação de ponto: $objeto.Propriedade. Para chamar um método, use $objeto.Metodo(). Exemplo:

# Obter o processo do bloco de notas
$proc = Get-Process -Name notepad -ErrorAction SilentlyContinue
if ($proc) {
    # Exibir o ID e o nome
    "Processo: $($proc.ProcessName), ID: $($proc.Id)"
    # Encerrar o processo (cuidado!)
    # $proc.Kill()
}

Muitos objetos também têm propriedades que são coleções, como Threads ou Modules. Você pode iterar sobre elas com foreach ou usar cmdlets como Select-Object e Where-Object para filtrar.

Get-Member

Como descobrir quais propriedades e métodos um objeto possui? Use o cmdlet Get-Member. Ele analisa um objeto e lista todos os seus membros (propriedades, métodos, eventos, etc.). Você pode usar o pipeline para passar objetos para ele:

Get-Process -Name powershell | Get-Member

A saída mostra uma tabela com os nomes, tipos e definições. Por exemplo, você verá Property para propriedades como CPU, Method para métodos como Kill(), e Event para eventos como Exited. Para ver apenas propriedades, use -MemberType Property:

Get-Process | Get-Member -MemberType Property

Você também pode usar Get-Member em objetos personalizados que você cria, como [PSCustomObject].

Por que isso muda tudo

A abordagem orientada a objetos do PowerShell traz vários benefícios práticos:

  • Consistência: Todos os cmdlets seguem o mesmo padrão de retornar objetos, facilitando o aprendizado e o uso.
  • Composição: Você pode encadear comandos com o pipeline, passando objetos inteiros de um cmdlet para outro. Por exemplo, Get-Process | Where-Object CPU -gt 10 | Stop-Process — sem parsing de texto.
  • Flexibilidade: Propriedades e métodos permitem acesso direto a dados e funcionalidades que, em shells tradicionais, exigiriam ferramentas externas ou scripts complexos.
  • Integração com .NET: Você pode usar qualquer classe .NET diretamente, ampliando enormemente as capacidades do PowerShell.

Por exemplo, para obter a data de modificação de um arquivo e formatá-la de uma maneira específica, você pode fazer:

$arquivo = Get-Item C:\temp\exemplo.txt
$dataFormatada = $arquivo.LastWriteTime.ToString("dd/MM/yyyy HH:mm:ss")
Write-Host "Modificado em: $dataFormatada"

Em um shell textual, você precisaria extrair a data da saída do comando dir e depois reformatá-la com expressões regulares — muito mais propenso a erros.

Boas práticas

Ao trabalhar com objetos, lembre-se de:

  • Sempre explore objetos desconhecidos com Get-Member.
  • Prefira acessar propriedades em vez de fazer parsing de saída formatada.
  • Use Select-Object para escolher propriedades específicas e Where-Object para filtrar objetos.
  • Ao criar seus próprios objetos (com [PSCustomObject]), nomeie as propriedades de forma clara.

Exercícios

  1. Use Get-Process e Get-Member para listar todas as propriedades de um processo. Quantas propriedades do tipo Property existem?
  2. ✓ Resposta: Execute Get-Process | Get-Member -MemberType Property | Measure-Object. O número de propriedades pode variar com a versão do PowerShell, mas geralmente é em torno de 30. No Windows PowerShell 5.1, são 33 propriedades.
  3. Obtenha o processo do PowerShell atual (PID) e exiba seu nome e uso de memória (WorkingSet) em megabytes.
  4. ✓ Resposta:
    $proc = Get-Process -Id $pid
    "Nome: $($proc.ProcessName), Memória: $([math]::Round($proc.WorkingSet / 1MB, 2)) MB"
  5. Crie um objeto personalizado com as propriedades Nome, Idade e Cidade, e exiba-o.
  6. ✓ Resposta:
    $pessoa = [PSCustomObject]@{
        Nome = "João"
        Idade = 30
        Cidade = "São Paulo"
    }
    $pessoa
  7. Use Get-Service para listar serviços e filtre apenas aqueles que estão em execução (Status = 'Running'). Exiba o nome e o nome de exibição.
  8. ✓ Resposta:
    Get-Service | Where-Object Status -eq 'Running' | Select-Object Name, DisplayName
  9. Para um arquivo de sua escolha, use Get-Item e chame o método LastWriteTime para obter a data de modificação e, em seguida, use o método ToShortDateString() para exibi-la no formato curto.
  10. ✓ Resposta:
    $arquivo = Get-Item C:\Windows\System32\notepad.exe
    $data = $arquivo.LastWriteTime
    $data.ToShortDateString()

Referências