No PowerShell, tudo o que você manipula — comandos, variáveis, arquivos, serviços — são objetos .NET. Isso significa que cada elemento possui propriedades (dados) e métodos (ações) que podem ser acessados de forma consistente. Diferente de shells como Bash ou CMD, onde a saída é texto puro e você precisa usar ferramentas como grep, sed ou awk para extrair informações, no PowerShell você lida diretamente com objetos estruturados. Essa é a base da produtividade e flexibilidade do PowerShell.

Nesta aula, vamos entender o que são objetos no contexto do PowerShell, como explorar suas propriedades e métodos, e por que essa abordagem orientada a objetos transforma a administração de sistemas e a automação de tarefas.

Objetos vs texto

Em shells tradicionais, a saída dos comandos é sempre texto. Por exemplo, no Linux, o comando ls -l retorna uma lista formatada de arquivos, mas para obter o nome do arquivo, você precisa usar expressões regulares ou cortar colunas. No PowerShell, o equivalente Get-ChildItem retorna objetos do tipo System.IO.FileInfo ou System.IO.DirectoryInfo, cada um com propriedades como Name, Length, LastWriteTime, etc. Você pode acessar esses dados diretamente sem parsear texto.

Essa diferença é crucial: enquanto no Bash você precisa de ferramentas externas para manipular texto, no PowerShell você usa cmdlets que operam sobre objetos. Por exemplo, para listar apenas os nomes de arquivos com mais de 1MB, no Bash você faria algo como ls -l | awk '$5 > 1048576 {print $9}'. No PowerShell, basta: Get-ChildItem | Where-Object { $_.Length -gt 1MB } | Select-Object Name. Isso é mais legível, menos propenso a erros e mais fácil de manter.

Propriedades e métodos

Um objeto no PowerShell é uma instância de uma classe .NET. Propriedades são atributos que descrevem o objeto (como cor, tamanho, nome). Métodos são ações que o objeto pode executar (como abrir, fechar, converter). Por exemplo, um objeto System.String (string) tem a propriedade Length e métodos como ToUpper() e Replace(). Você acessa propriedades com o operador ponto: $objeto.propriedade. Métodos são chamados com parênteses: $objeto.metodo().

Exemplo prático: suponha que você tenha uma variável com um caminho de arquivo. O objeto System.IO.FileInfo pode ser obtido com Get-Item. Veja como acessar propriedades e métodos:

$arquivo = Get-Item -Path "C:\temp\exemplo.txt"
# Propriedades
$arquivo.Name       # Saída: exemplo.txt
$arquivo.Length     # Tamanho em bytes
$arquivo.IsReadOnly # Booleano

# Métodos
$arquivo.Delete()   # Exclui o arquivo (cuidado!)
$arquivo.CopyTo("C:\backup\exemplo.txt") # Copia o arquivo

É importante notar que muitos cmdlets retornam coleções de objetos. Nesse caso, você pode usar o pipeline para passar objetos de um cmdlet para outro, e cada cmdlet no pipeline opera sobre os objetos recebidos. Por exemplo, Get-Process | Where-Object { $_.CPU -gt 100 } filtra processos com alto uso de CPU.

Get-Member

O cmdlet Get-Member é a ferramenta essencial para descobrir as propriedades e métodos de qualquer objeto. Você pode usá-lo passando um objeto pelo pipeline ou diretamente com o parâmetro -InputObject. Ele lista todos os membros (propriedades, métodos, eventos) disponíveis no objeto. Por exemplo:

Get-Process | Get-Member
# ou
Get-Member -InputObject (Get-Process -Id $pid)

A saída mostra uma tabela com colunas: Name (nome do membro), MemberType (tipo: Property, Method, etc.) e Definition (assinatura ou tipo). Para propriedades, a Definition mostra o tipo de dado (ex: string Name {get;}). Para métodos, mostra os parâmetros (ex: void Kill()). Use Get-Member -MemberType Property para filtrar apenas propriedades, ou -MemberType Method para métodos.

Exemplo prático: descubra as propriedades de um arquivo:

Get-Item -Path "C:\Windows\notepad.exe" | Get-Member -MemberType Property

Isso retorna propriedades como Attributes, CreationTime, Exists, Extension, FullName, LastAccessTime, LastWriteTime, Length, Name.

Além disso, Get-Member aceita o parâmetro -Static para ver membros estáticos da classe, e -Force para incluir membros ocultos. É uma ferramenta indispensável para explorar objetos desconhecidos.

Por que isso muda tudo

A abordagem orientada a objetos no PowerShell muda fundamentalmente a maneira como você interage com o sistema. Em vez de lidar com saídas de texto frágeis, você tem acesso direto a dados estruturados e ações padronizadas. Isso traz várias vantagens:

  • Consistência: Todos os cmdlets seguem o padrão verbo-substantivo e retornam objetos .NET. Você pode usar os mesmos cmdlets (Where-Object, Select-Object, Sort-Object) para processar qualquer tipo de objeto.
  • Facilidade de automação: Você pode acessar propriedades e chamar métodos sem depender de ferramentas externas. Por exemplo, para renomear muitos arquivos, você usa Rename-Item diretamente, em vez de construir comandos com sed.
  • Pipeline poderoso: O pipeline passa objetos, não texto. Isso permite encadear operações complexas de forma clara. Por exemplo: Get-Service | Where-Object { $_.Status -eq 'Stopped' } | Start-Service inicia todos os serviços parados.
  • Integração com .NET: Você pode usar qualquer classe .NET diretamente. Por exemplo, para baixar um arquivo da web: (New-Object System.Net.WebClient).DownloadFile('url', 'destino'). Isso expande enormemente as possibilidades.
  • Depuração e descoberta: Com Get-Member, você pode explorar qualquer objeto em tempo real, facilitando o aprendizado e a solução de problemas.

Em resumo, a mentalidade de “tudo são objetos” é o que diferencia o PowerShell de outros shells. Ao dominar esse conceito, você será capaz de escrever scripts mais robustos, legíveis e eficientes.

Boas práticas

  • Sempre use Get-Member quando encontrar um objeto desconhecido para entender sua estrutura.
  • Prefira acessar propriedades a parsear texto. Se um cmdlet retorna texto, talvez haja um cmdlet melhor que retorna objetos.
  • Ao criar funções, retorne objetos personalizados com [PSCustomObject] para manter a consistência.
  • Evite usar Format-Table ou Format-List no pipeline se você for processar os dados adiante; use apenas para exibição final.

Referências

Exercícios

  1. Use Get-Process para listar todos os processos em execução. Em seguida, filtre apenas aqueles com mais de 100 MB de memória (WorkingSet) e exiba o nome e o WorkingSet em MB. Use objetos e propriedades, não texto.

    ✓ Resposta:
    Get-Process | Where-Object { $_.WorkingSet -gt 100MB } | Select-Object Name, @{Name='WorkingSetMB'; Expression={[math]::Round($_.WorkingSet / 1MB, 2)}}
  2. Obtenha o objeto referente ao arquivo C:\Windows\notepad.exe usando Get-Item. Use Get-Member para listar todas as propriedades desse objeto. Em seguida, exiba o valor da propriedade VersionInfo (que é um objeto).

    ✓ Resposta:
    $arquivo = Get-Item -Path "C:\Windows\notepad.exe"
    $arquivo | Get-Member -MemberType Property
    $arquivo.VersionInfo
  3. Crie uma variável do tipo string com seu nome completo. Use métodos do objeto string para converter para maiúsculas e substituir seu sobrenome por “PowerShell”. Exiba o resultado.

    ✓ Resposta:
    $nome = "João Silva"
    $nome.ToUpper()
    $nome.Replace("Silva", "PowerShell")
  4. Liste todos os serviços do sistema. Para cada serviço que estiver parado (Status = 'Stopped'), exiba o nome do serviço e o tipo de inicialização (StartType). Use propriedades dos objetos.

    ✓ Resposta:
    Get-Service | Where-Object { $_.Status -eq 'Stopped' } | Select-Object Name, StartType
  5. Utilizando Get-ChildItem no diretório atual, obtenha a lista de arquivos (não pastas). Para cada arquivo, exiba o nome, o tamanho em KB e a data da última modificação. Use formatação personalizada com Select-Object.

    ✓ Resposta:
    Get-ChildItem -File | Select-Object Name, @{Name='SizeKB'; Expression={[math]::Round($_.Length / 1KB, 2)}}, LastWriteTime