Tenho um fluxo de trabalho que é bem exigente com os PSCustomObjects que recebe. Costumo usar Select-Object
para obter as propriedades dos objetos que quero manter e, às vezes, preciso converter alguns dos valores para formatos mais utilizáveis. A maneira mais fácil de fazer isso é usar a @{Name='Name'; Expression = {'Expression'}}
técnica.
MAS, essa técnica bagunça o PSCustomObject de uma forma que bloqueia meu fluxo de trabalho futuro.
O problema pode ser reproduzido assim:
$object = [pscustomobject]@{
Text = "This is a string"
}
Na saída abaixo, a definição para string é 'string Text=This is a string'
$object | Select-Object * | Get-Member
<# Outputs
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Text NoteProperty string Text=This is a string
#>
Ao adicionar uma nova NoteProperty com a técnica Select-Object, a definição é 'System.String Text2=This is a string'
É isso que faz meu próximo cmdlet ser executado.
$WhatHappensToText = $object | Select-Object @{Name='Text'; Expression={$_.Text}}
$WhatHappensToText | Get-Member
<# Outputs
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Text NoteProperty System.String Text=This is a string
#>
Ao remover o excedente como abaixo, a definição retorna para 'string Text2=This is a string'
Exportar para Clixml e reimportar faz o mesmo
$WhatHappensToText | ConvertTo-Json | ConvertFrom-Json | Get-Member
<# Outputs
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Text NoteProperty string Text=This is a string
#>
Se eu adicionar a nova NoteProperty assim, a definição será 'string Text2=This is a string' como eu gosto
$object2 = $object | Select-Object *
$object2 | foreach-object {$_ | Add-Member -MemberType NoteProperty -Name Text2 -Value $_.Text}
$object2 | Get-Member
<# Outputs
TypeName: Selected.System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetType Method type GetType()
ToString Method string ToString()
Text NoteProperty string Text=This is a string
Text2 NoteProperty string Text2=This is a string
#>
Tenho as seguintes perguntas:
Por que a @{Name='Name'; Expression = {'Expression'}}
técnica adiciona System.String à Definição e não string como no cenário Add-Member?
Existe uma maneira de fazer a @{Name='Name'; Expression = {'Expression'}}
técnica adicionar uma string e não um System.String?