Como criar um object que gera uma lista (não uma tabela)

Este é um spin-off de outra questão que está localizada aqui: Formatando um Objeto como uma lista de aparência ordenada A base do argumento, creio eu, estava errada, já que não estamos lidando com a formatação do object depois. Isso é apenas para aparências, como mostrado pelo console, mas pode ter relação com a integridade do object enquanto você manipula a variável que contém o object.

O que eu preciso é criar um object que inerentemente produza uma lista (não uma tabela). Eu sei que é possível porque eu testei muitas funções que eu não escrevi e os objects criados são na verdade listas. Não há necessidade de usar o Format-List para distorcer ou moldar o que já está lá. Eu simplesmente não consigo entender porque às vezes a saída é uma lista ou uma tabela. Não tenho certeza de onde está a mágica. No entanto, sei que quando executo $Host antes de executar a variável que contém o object criado, obtenho o object que o Host produz, que é uma lista, e que forma o object posteriormente também como uma lista que normalmente seria mostrada como uma tabela. Claro, isso pode dar o resultado que eu quero, mas eu não estou olhando para mostrar as informações do Host. Então, qual é a solução para isso, eu gostaria que alguém pudesse explicar isso.

O PowerShell faz alguma formatação padrão quando apresenta dados / objects ao usuário. Normalmente, os objects são exibidos em forma de tabela quando têm até 4 propriedades e em forma de lista quando têm mais de 4 propriedades.

Se você gerar várias coisas seguidas, o PowerShell aplicará o formato (lista / tabela) do primeiro object a todos os objects subseqüentes. Não sei o raciocínio exato por trás desse comportamento, mas presumivelmente é tornar a saída mais consistente.

Demonstração:

 PS C: \> $ o1 = Novo-Objeto -Tipo PSObject -Propriedade @ {a = 1; b = 2; c = 3; d = 4; e = 5}
 PS C: \> $ o2 = Novo-Objeto -Tipo PSObject -Propriedade @ {x = 'foo'; y = 'bar'}
 PS C: \> $ o1

 c: 3
 e: 5
 d: 4
 b: 2
 um: 1

 PS C: \> $ o2

 yx
 - -
 bar foo

 PS C: \> $ o1;  $ o2

 c: 3
 e: 5
 d: 4
 b: 2
 um: 1

 y: bar
 x: foo

Cuidado, no entanto, que depender desse comportamento pode levar a resultados indesejados se você gerar objects na ordem errada:

 PS C: \> $ o2;  $ o1

 yx
 - -
 bar foo # ← propriedades de $ o2 
                                                   # ← linha vazia por $ o1!

$o1 aparece como uma linha em branco na saída acima, porque a saída $o2 primeiro estabelece o formato de saída tabular com as colunas y e x , mas $o1 não possui essas propriedades. As propriedades ausentes são exibidas como valores em branco na saída tabular, enquanto as propriedades adicionais são omitidas da saída. Também há casos em que você pode obter a saída do segundo object / lista no formulário de lista (executado por exemplo Get-Process; Get-ChildItem em um console do PowerShell).

Você pode forçar que objects subseqüentes ou matrizes de objects sejam exibidos como tabelas (ou listas) separadas, passando-os pelo cmdlet Format-Table (ou Format-List ):

 PS C: \> $ o2;  $ o1 |  Format-Table

 yx
 - -
 bar foo


               Cedba
               - - - - -
               3 5 4 2 1

Você também pode forçar o PowerShell a exibir cada variável individualmente canalizando-as (por exemplo) Out-Default :

 PS C: \> $ o2 |  Out-Default;  $ o1 |  Out-Default

 yx
 - -
 bar foo

 c: 3
 e: 5
 d: 4
 b: 2
 um: 1

Observe, no entanto, que isso é gravado no console, portanto, a saída resultante não pode mais ser capturada, redirecionada ou canalizada. Use isso somente se você quiser exibir algo para um usuário.

Para obter informações adicionais sobre formatação de saída do PowerShell, consulte aqui .


Existem maneiras de alterar o comportamento padrão de como um object é exibido, mas infelizmente elas não são exatamente diretas. Por um lado, você pode definir um conjunto de propriedades de exibição padrão para que o PowerShell exiba nem todas as propriedades, mas apenas um subconjunto específico.

 PS C: \> $ props = 'c', 'd'
 PS C: \> $ default = Novo Objeto Management.Automation.PSPropertySet ('DefaultDisplayPropertySet', [string []] $ props)
 PS C: \> $ members = [Management.Automation.PSMemberInfo []] @ ($ padrão)
 PS C: \> $ o1 |  Add-Member MemberSet PSStandardMembers $ membros
 PS C: \> $ o1

                 CD
                 - -
                 3 4

Você ainda pode obter todas as propriedades exibidas usando Format-List * :

 PS C: \> $ o1 |  Lista de formatos *

 c: 3
 e: 5
 d: 4
 b: 2
 um: 1

Definir o conjunto de propriedades de exibição padrão não permite que você defina o formato de saída. Para fazer isso, você provavelmente precisará escrever um arquivo de formatação personalizado. Para que isso funcione, você provavelmente também precisa definir um tipo personalizado para seus objects.

 $formatFile = "$HOME\Documents\WindowsPowerShell\Your.Format.ps1xml" $typeFile = "$HOME\Documents\WindowsPowerShell\Your.Type.ps1xml" @'     Default  Foo.Bar   ...     '@ | Set-Content $formatFile Update-FormatData -AppendPath $formatFile @'    Foo.Bar  ...    '@ | Set-Content $typeFile Update-TypeData -AppendPath $typeFile $o2.PSTypeNames.Insert(0, 'Foo.Bar') 

Jeffrey Hicks escreveu uma série de artigos sobre o assunto que você pode querer ler.


Com tudo isso dito, eu não recomendaria seguir esse caminho a menos que você tenha razões muito convincentes para fazê-lo. Eu tentei explicar isso antes, mas o @TesselatingHeckler colocou isso muito mais concisamente do que eu, então vou citá-lo sobre isso:

PowerShell não é bash, tem uma separação de conteúdo e apresentação, como HTML e CSS.

O que você normalmente deseja fazer no PowerShell é manter seus dados em objects e ter as propriedades desses objects contendo os dados “brutos” (isto é, sem formatação). Isso dá a você mais flexibilidade para processar seus dados. Dados formatados geralmente só atrapalham, porque obriga você a analisar / converter os dados novamente. Formate seus dados somente quando precisar exibi-los para um usuário e use os cmdlets Format-* para fazer isso. E se a sua saída é destinada para processamento adicional: não se preocupe em formatá-la em primeiro lugar. Deixe para o usuário como ele deseja exibir os dados.