PSCustomObject
Esta aula explora o uso de PSCustomObject no PowerShell, uma estrutura leve e eficiente para criar objetos customizados com propriedades nomeadas. Você aprenderá a sintaxe [PSCustomObject]@{}, como manipular propriedades e casos de uso práticos para organizar dados em scripts.
No PowerShell, objetos são a base de tudo. Quase tudo que você manipula – arquivos, processos, serviços – é representado como um objeto com propriedades e métodos. Mas e quando você precisa criar seus próprios objetos para representar dados personalizados, como um registro de usuário, um item de inventário ou um resultado de uma consulta? É aí que entra o PSCustomObject, uma maneira eficiente e leve de criar objetos customizados sem a complexidade de classes formais.
O PSCustomObject é uma construção especial do PowerShell que permite criar objetos com um conjunto fixo de propriedades de forma rápida e com sintaxe limpa. Diferente de usar New-Object PSObject ou Add-Member, o PSCustomObject é otimizado para desempenho e legibilidade. Nesta aula, vamos explorar como criá-los, acessar e modificar suas propriedades, e aplicá-los em cenários reais.
Criando objetos customizados
Antes do PSCustomObject, era comum criar objetos usando New-Object PSObject e depois adicionar propriedades com Add-Member. Esse método funciona, mas é verboso e menos performático. Com o PSCustomObject, você define todas as propriedades de uma só vez, usando uma hashtable.
A sintaxe básica é: [PSCustomObject]@{ Propriedade1 = 'Valor1'; Propriedade2 = 'Valor2' }. O resultado é um objeto com as propriedades definidas, que você pode armazenar em uma variável, passar por pipelines, ou usar em expressões.
# Criando um objeto customizado simples
$usuario = [PSCustomObject]@{
Nome = 'João Silva'
Email = 'joao@exemplo.com'
Idade = 30
}
# Exibindo o objeto
$usuario
No exemplo acima, $usuario é um objeto com três propriedades: Nome, Email e Idade. Você pode acessar cada propriedade usando a notação de ponto: $usuario.Nome. Além disso, objetos criados dessa forma são compatíveis com cmdlets como Select-Object, Where-Object e Export-Csv.
[PSCustomObject]@{}
A expressão [PSCustomObject]@{} é um acelerador de tipo (type accelerator) que instrui o PowerShell a interpretar a hashtable como um objeto customizado. A hashtable deve conter pares chave-valor, onde a chave se torna o nome da propriedade e o valor, o valor da propriedade. É importante notar que a ordem das propriedades é preservada a partir do PowerShell 3.0.
Você também pode criar objetos vazios e depois adicionar propriedades, mas não é recomendado porque o PSCustomObject é imutável em termos de estrutura (não é possível adicionar novas propriedades depois de criado, a menos que use Add-Member). Para objetos dinâmicos, prefira PSObject ou classes do PowerShell 5.0+.
# Criando um objeto com diferentes tipos de valores
$produto = [PSCustomObject]@{
Nome = 'Notebook'
Preco = 2500.00
Quantidade = 10
Disponivel = $true
}
# Acessando propriedades
$produto.Nome
$produto.Preco
# Modificando um valor (isso é permitido)
$produto.Preco = 2400.00
$produto
Observe que você pode modificar o valor de uma propriedade existente, mas não pode adicionar uma nova propriedade diretamente. Se precisar adicionar, use $produto | Add-Member -MemberType NoteProperty -Name 'Categoria' -Value 'Eletrônicos'.
Propriedades
As propriedades de um PSCustomObject são do tipo NoteProperty. Você pode acessá-las com notação de ponto ($objeto.Propriedade) ou com a sintaxe de dicionário ($objeto.'Propriedade'). Além disso, é possível listar todas as propriedades com $objeto.PSObject.Properties.
Para scripts mais complexos, você pode querer adicionar métodos ou outros tipos de membros. Embora PSCustomObject não suporte métodos nativamente, você pode usar Add-Member para adicionar ScriptMethod, ScriptProperty, etc. No entanto, para objetos com comportamento, considere usar classes.
# Listando propriedades
$usuario.PSObject.Properties | ForEach-Object { $_.Name, $_.Value }
# Usando Select-Object para selecionar propriedades
$usuario | Select-Object Nome, Idade
# Usando Where-Object para filtrar
$usuarios = @(
[PSCustomObject]@{ Nome = 'Ana'; Idade = 25 }
[PSCustomObject]@{ Nome = 'Carlos'; Idade = 35 }
[PSCustomObject]@{ Nome = 'Beatriz'; Idade = 28 }
)
$usuarios | Where-Object { $_.Idade -gt 30 }
Casos de uso
O PSCustomObject é extremamente útil em várias situações:
- Exportação de dados: Você pode criar objetos customizados e exportá-los para CSV, JSON ou XML usando cmdlets como
Export-Csv. - Relatórios: Crie objetos com informações de sistema, como uso de disco, processos em execução, etc., e formate a saída.
- Transformação de dados: Ao processar arquivos de log ou dados de APIs, você pode converter cada registro em um
PSCustomObjectpara facilitar a manipulação. - Simulação de objetos de banco de dados: Represente linhas de uma tabela como objetos customizados.
# Exemplo: relatório de serviços em execução
$servicos = Get-Service | Where-Object { $_.Status -eq 'Running' } | ForEach-Object {
[PSCustomObject]@{
Nome = $_.Name
NomeExibicao = $_.DisplayName
Tipo = $_.ServiceType
Iniciado = $_.StartType
}
}
$servicos | Export-Csv -Path 'C:\relatorio_servicos.csv' -NoTypeInformation
Boas práticas
- Use nomes de propriedades consistentes e significativos.
- Evite criar objetos muito grandes; prefira coleções de objetos pequenos.
- Considere usar classes do PowerShell 5.0+ quando precisar de métodos ou validação de propriedades.
- Para scripts que serão reutilizados, defina funções que retornam
PSCustomObject.
Referências
- About Object Creation - Microsoft Docs
- Everything about PSCustomObject - Microsoft Docs
- Add-Member - Microsoft Docs
- About Hashtables - Microsoft Docs
- Export-Csv - Microsoft Docs
Exercícios
- Crie um script que leia o conteúdo de um arquivo CSV hipotético (simule com uma lista de hashtables) e converta cada linha em um PSCustomObject. Use o seguinte conjunto de dados: Nome, Cidade, Idade. Em seguida, exiba apenas os objetos onde a idade é maior que 30.
- Crie uma função chamada
New-Pessoaque aceite parâmetrosNome,SobrenomeeIdadee retorne um PSCustomObject com essas propriedades, mais uma propriedade calculadaNomeCompletoque concatena Nome e Sobrenome. - Dado um array de PSCustomObject representando produtos (com propriedades: Nome, Preco, Quantidade), escreva um script que calcule o valor total do estoque (Preco * Quantidade) e exiba o resultado.
- Use um PSCustomObject para representar um processo em execução (com propriedades: Nome, PID, Memória em MB). Em seguida, crie uma lista com três processos fictícios e ordene por consumo de memória decrescente.
- Crie um script que, usando PSCustomObject, gere um relatório com as informações de três arquivos de uma pasta (simule os arquivos). Para cada arquivo, inclua: Nome, Tamanho em KB, Data de modificação. Exporte o relatório para um arquivo CSV chamado 'relatorio_arquivos.csv'.
# Dados simulados (como se viesse de um CSV)
$dados = @(
@{ Nome = 'Alice'; Cidade = 'São Paulo'; Idade = 28 },
@{ Nome = 'Bob'; Cidade = 'Rio de Janeiro'; Idade = 35 },
@{ Nome = 'Carol'; Cidade = 'Belo Horizonte'; Idade = 22 }
)
# Converter para PSCustomObject
$objetos = $dados | ForEach-Object {
[PSCustomObject]@{
Nome = $_.Nome
Cidade = $_.Cidade
Idade = $_.Idade
}
}
# Filtrar idade > 30
$objetos | Where-Object { $_.Idade -gt 30 }
function New-Pessoa {
param(
[string]$Nome,
[string]$Sobrenome,
[int]$Idade
)
[PSCustomObject]@{
Nome = $Nome
Sobrenome = $Sobrenome
Idade = $Idade
NomeCompleto = "$Nome $Sobrenome"
}
}
# Exemplo de uso
$pessoa = New-Pessoa -Nome 'Maria' -Sobrenome 'Santos' -Idade 32
$pessoa
$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 }
)
$valorTotal = 0
foreach ($produto in $produtos) {
$valorTotal += $produto.Preco * $produto.Quantidade
}
Write-Host "Valor total do estoque: R$ $valorTotal"
$processos = @(
[PSCustomObject]@{ Nome = 'chrome.exe'; PID = 1234; MemoriaMB = 350.5 },
[PSCustomObject]@{ Nome = 'notepad.exe'; PID = 5678; MemoriaMB = 45.2 },
[PSCustomObject]@{ Nome = 'powershell.exe'; PID = 9012; MemoriaMB = 120.0 }
)
$processosOrdenados = $processos | Sort-Object -Property MemoriaMB -Descending
$processosOrdenados | Format-Table -AutoSize
# Simulação de arquivos
$arquivos = @(
[PSCustomObject]@{
Nome = 'documento.txt'
TamanhoKB = 12.5
DataModificacao = Get-Date '2025-03-10'
},
[PSCustomObject]@{
Nome = 'foto.jpg'
TamanhoKB = 1024.0
DataModificacao = Get-Date '2025-03-12'
},
[PSCustomObject]@{
Nome = 'planilha.xlsx'
TamanhoKB = 256.3
DataModificacao = Get-Date '2025-03-15'
}
)
$arquivos | Export-Csv -Path 'relatorio_arquivos.csv' -NoTypeInformation
Write-Host 'Relatório exportado com sucesso.'