Tudo são objetos
Esta aula explora o conceito fundamental de que tudo no PowerShell é um objeto, contrastando com shells baseadas em texto. Você aprenderá a inspecionar propriedades e métodos com Get-Member, e entenderá como essa abordagem orientada a objetos torna a automação mais poderosa e flexível.
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-Objectpara escolher propriedades específicas eWhere-Objectpara filtrar objetos. - Ao criar seus próprios objetos (com
[PSCustomObject]), nomeie as propriedades de forma clara.
Exercícios
- Use
Get-ProcesseGet-Memberpara listar todas as propriedades de um processo. Quantas propriedades do tipoPropertyexistem? - Obtenha o processo do PowerShell atual (PID) e exiba seu nome e uso de memória (WorkingSet) em megabytes.
- Crie um objeto personalizado com as propriedades Nome, Idade e Cidade, e exiba-o.
- Use
Get-Servicepara listar serviços e filtre apenas aqueles que estão em execução (Status = 'Running'). Exiba o nome e o nome de exibição. - Para um arquivo de sua escolha, use
Get-Iteme chame o métodoLastWriteTimepara obter a data de modificação e, em seguida, use o métodoToShortDateString()para exibi-la no formato curto.
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.$proc = Get-Process -Id $pid
"Nome: $($proc.ProcessName), Memória: $([math]::Round($proc.WorkingSet / 1MB, 2)) MB"$pessoa = [PSCustomObject]@{
Nome = "João"
Idade = 30
Cidade = "São Paulo"
}
$pessoaGet-Service | Where-Object Status -eq 'Running' | Select-Object Name, DisplayName$arquivo = Get-Item C:\Windows\System32\notepad.exe
$data = $arquivo.LastWriteTime
$data.ToShortDateString()