PSCustomObject
Esta aula ensina a criar e utilizar objetos customizados no PowerShell com PSCustomObject, abordando desde a sintaxe básica até casos de uso práticos. Você aprenderá a estruturar dados de forma flexível e eficiente, melhorando a organização e a legibilidade dos seus scripts.
No PowerShell, tudo é um objeto, mas muitas vezes precisamos de estruturas de dados que não correspondem exatamente aos tipos nativos. É aí que entra o PSCustomObject, uma ferramenta poderosa para criar objetos personalizados com as propriedades que você definir. Esta aula vai te ensinar a criar, manipular e aplicar esses objetos em situações reais.
Dominar o PSCustomObject é essencial para scripts mais limpos e para a saída de dados estruturados, especialmente quando você precisa combinar informações de diferentes fontes ou criar relatórios personalizados.
Criando objetos customizados
Antes do PowerShell 3.0, criar objetos customizados era mais verboso, usando New-Object com PSObject. Hoje, a maneira mais comum e concisa é usando o acelerador de tipo [PSCustomObject] seguido de uma hashtable. Mas também é possível usar o cmdlet New-Object e depois adicionar propriedades com Add-Member. Vamos focar na abordagem moderna.
Exemplo básico:
$pessoa = [PSCustomObject]@{
Nome = 'João'
Idade = 30
Cidade = 'São Paulo'
}
$pessoa
Isso cria um objeto com três propriedades: Nome, Idade e Cidade. Você pode acessá-las como qualquer propriedade de objeto: $pessoa.Nome.
[PSCustomObject]@{}
Essa sintaxe combina o acelerador de tipo [PSCustomObject] com uma hashtable (@{}). A hashtable define as propriedades e seus valores iniciais. É importante notar que a ordem das propriedades é preservada (a partir do PowerShell 3.0).
Detalhes importantes:
- A hashtable deve ter chaves como strings (nomes das propriedades).
- Os valores podem ser de qualquer tipo, inclusive outros objetos ou arrays.
- Propriedades podem ser adicionadas posteriormente com
Add-Memberou simplesmente atribuindo um valor a uma propriedade inexistente (embora isso não seja recomendado para objetos criados com[PSCustomObject]– é mais seguro usarAdd-Member).
Exemplo com propriedades de diferentes tipos:
$computador = [PSCustomObject]@{
Nome = 'SRV01'
IP = '192.168.1.10'
Online = $true
Discos = @('C:', 'D:')
}
$computador
Você também pode criar objetos vazios e depois preenchê-los:
$obj = [PSCustomObject]@{}
$obj | Add-Member -MemberType NoteProperty -Name 'Nome' -Value 'Teste'
$obj | Add-Member -MemberType NoteProperty -Name 'Valor' -Value 100
$obj
Propriedades
Propriedades de um PSCustomObject são como variáveis dentro do objeto. Você pode defini-las na criação ou adicioná-las depois. Além de propriedades simples (NoteProperty), você pode adicionar métodos (ScriptMethod) ou propriedades calculadas.
Exemplo de adição dinâmica com Add-Member:
$carro = [PSCustomObject]@{
Marca = 'Ford'
Modelo = 'Focus'
}
$carro | Add-Member -MemberType NoteProperty -Name 'Ano' -Value 2020
$carro | Add-Member -MemberType ScriptMethod -Name 'Ligar' -Value { Write-Host 'Vruum!' }
$carro.Ligar()
Para remover uma propriedade, você pode usar Remove-Variable no objeto, mas isso não é comum. Melhor é criar um novo objeto sem a propriedade indesejada.
Propriedades podem ser acessadas e modificadas diretamente:
$carro.Ano = 2021
$carro.Ano
Casos de uso
PSCustomObject é extremamente útil em várias situações:
- Saída de dados estruturados: Em vez de strings soltas, você pode emitir objetos que podem ser processados por outros cmdlets.
- Relatórios: Combinar informações de várias fontes em um único objeto para exportar para CSV, JSON, etc.
- Simulação de classes: Antes do PowerShell 5.0 com classes,
PSCustomObjectera a principal forma de criar objetos com propriedades. - Conversão de dados: Transformar hashtables ou arrays em objetos para facilitar o acesso.
Exemplo prático: coletar informações de processos e criar um relatório customizado.
$processos = Get-Process | Select-Object -First 5
$relatorio = foreach ($proc in $processos) {
[PSCustomObject]@{
Nome = $proc.Name
PID = $proc.Id
MemoriaMB = [math]::Round($proc.WorkingSet / 1MB, 2)
Threads = $proc.Threads.Count
}
}
$relatorio | Export-Csv -Path 'processos.csv' -NoTypeInformation
Isso gera um CSV limpo com apenas as colunas desejadas.
Boas práticas
- Use
[PSCustomObject]@{}sempre que possível, é mais legível. - Evite adicionar propriedades após a criação se puder defini-las todas de uma vez.
- Para objetos que serão usados como saída, considere usar
[PSCustomObject]em vez de hashtables, pois os objetos têm comportamento consistente em pipelines. - Se precisar de métodos, use
Add-Membercom ScriptMethod, mas lembre-se de que isso pode tornar o objeto mais pesado.
Referências
- New-Object (Microsoft.PowerShell.Utility)
- Add-Member (Microsoft.PowerShell.Utility)
- Everything you wanted to know about PSCustomObject
- SS64 - PowerShell Objects
- PowerShell.org - Understanding PSCustomObject
Exercícios
Crie um objeto PSCustomObject chamado
$alunocom as propriedades Nome, Idade e Curso. Atribua valores de sua escolha e exiba o objeto.✓ Resposta:$aluno = [PSCustomObject]@{ Nome = 'Maria' Idade = 22 Curso = 'Engenharia' } $alunoAdicione uma propriedade 'Nota' (tipo double) ao objeto
$alunocriado no exercício 1 usandoAdd-Member. Atribua um valor e exiba a propriedade.✓ Resposta:$aluno | Add-Member -MemberType NoteProperty -Name 'Nota' -Value 8.5 $aluno.NotaCrie uma lista de objetos PSCustomObject representando 3 produtos (Nome, Preco, Quantidade). Calcule e exiba o valor total em estoque (soma de Preco * Quantidade para cada produto).
✓ Resposta:$produtos = @( [PSCustomObject]@{ Nome = 'Caneta'; Preco = 1.50; Quantidade = 100 }, [PSCustomObject]@{ Nome = 'Caderno'; Preco = 15.00; Quantidade = 50 }, [PSCustomObject]@{ Nome = 'Borracha'; Preco = 0.75; Quantidade = 200 } ) $total = ($produtos | ForEach-Object { $_.Preco * $_.Quantidade } | Measure-Object -Sum).Sum Write-Host "Valor total em estoque: R$ $total"Usando
Get-Process, crie um objeto PSCustomObject para cada processo com as propriedades: Nome, PID, e MemoriaMB (WorkingSet em MB arredondado). Selecione apenas os 5 primeiros processos. Exiba os objetos.✓ Resposta:Get-Process | Select-Object -First 5 | ForEach-Object { [PSCustomObject]@{ Nome = $_.Name PID = $_.Id MemoriaMB = [math]::Round($_.WorkingSet / 1MB, 2) } }Crie um objeto PSCustomObject vazio, adicione uma propriedade 'Nome' e um método 'Saudacao' que escreve 'Olá, [Nome]!'. Execute o método.
✓ Resposta:$obj = [PSCustomObject]@{} $obj | Add-Member -MemberType NoteProperty -Name 'Nome' -Value 'Ana' $obj | Add-Member -MemberType ScriptMethod -Name 'Saudacao' -Value { Write-Host "Olá, $($this.Nome)!" } $obj.Saudacao()