read parse how from convertfrom json powershell formatting output-formatting

parse - Formatear instancias[pscustomobject] devueltas por Invoke-RestMethod o ConvertFrom-Json



powershell convertfrom json (2)

Estoy intentando crear una tabla a partir de un archivo JSON que recibo de una API RESTful.

Cuando imprimo la propiedad del objeto json obtengo un resultado como este:

PS> Write-Output JSON.Object Object1 : @{key1=property; key2=property; key3=property; key4=property} Object2 : @{key1=property; key2=property; key3=property; key4=property} Object3 : @{key1=property; key2=property; key3=property; key4=property} Object4 : @{key1=property; key2=property; key3=property; key4=property}

La salida que me gustaría ver es esta:

Name key1 key2 key3 key4 ----- ---- ---- ---- ---- Object1 property property property property Object2 property property property property Object3 property property property property

Además, ¿es posible evitar mostrar una clave específica y sus propiedades?

Ejemplo:

Name key1 key2 key4 # ← Not displaying key3 ----- ---- ---- ---- Object1 property property property Object2 property property property Object3 property property property


Debe agregar el nombre clave principal como nombre de propiedad a los objetos anidados:

$json.Object | ForEach-Object { foreach ($p in $_.PSObject.Properties) { $p.Value | Select-Object @{n=''Name'';e={$p.Name}},* } }

Tenga en cuenta que PowerShell representará el resultado en forma de lista de forma predeterminada, ya que sus objetos tienen más de 4 propiedades. Format-List -AutoSize a través de Format-List -AutoSize para obtener resultados tabulares.


Para complementar la elegante respuesta de Ansgar Wiecher con información de fondo :

Definamos la entrada de muestra que simula un único objeto anidado convertido a una instancia de PowerShell [pscustomobject] través de ConvertFrom-Json :

$objFromJson = [pscustomobject] @{ Object1 = [pscustomobject] @{key1=''o11''; key2=''o12''; key3=''o13''; key4=''o14''} Object2 = [pscustomobject] @{key1=''o21''; key2=''o22''; key3=''o23''; key4=''o24''} Object3 = [pscustomobject] @{key1=''o31''; key2=''o32''; key3=''o33''; key4=''o34''} Object4 = [pscustomobject] @{key1=''o41''; key2=''o42''; key3=''o43''; key4=''o44''} Object5 = [pscustomobject] @{key1=''o51''; key2=''o52''; key3=''o53''; key4=''o54''} }

$objFromJson salida $objFromJson da salida que está formateada como en la pregunta.

¿Por qué esto da como resultado el formato de salida que se muestra en la pregunta?

Para tipos como [pscustomobject] , que no tienen definiciones de formato explícitas definidas para ellos (a través de archivos *.ps1xml y cargados implícitamente en la sesión o explícitamente a través de Update-FormatData ), PowerShell decide qué formato predeterminado usar en función del número de propiedades del tipo:

  • Un tipo con hasta 4 propiedades usa implícitamente Format-Table
  • un tipo con 5 o más propiedades usa implícitamente Format-List

La entrada de muestra en la pregunta es, presumiblemente, abreviada ; con solo 4 propiedades, habría resultado una pantalla tabular .

Las propiedades mismas se representan llamando a .PSObject.ToString() en sus valores, que es típicamente la misma representación que obtendría si .PSObject.ToString() referencia al objeto dentro de una cadena de comillas dobles, excepto que esta última siempre usa el formato invariante de cultura, mientras que .ToString() respetará la cultura actual, si el tipo lo admite.

En el caso de una instancia [pscustomobject] , esto da como resultado una representación que se asemeja a un literal hashtable, pero no es una (para información de fondo, vea esta respuesta mía); p.ej:

> $objFromJson.Object1.PSObject.ToString() @{key1=o11; key2=o12; key3=o13; key4=o14}

Remodelación de los datos como se desee

No hay forma de usar cmdlets de formateo como Format-Table directamente para obtener el resultado deseado; los datos deben reformarse primero:

Específicamente, las propiedades del objeto $objFromJson deben $objFromJson formar en una colección de objetos personalizados :

  • cuya propiedad Name contiene el nombre de una propiedad dada, y

  • cuyas otras propiedades son las propiedades del objeto del valor de esa propiedad; en otras palabras: las propiedades del valor de la propiedad de entrada deben ser propiedades del propio objeto de salida.

La extracción de $objFromJson las propiedades es facilitada por PowerShell al agregar (entre otras) una propiedad .PSObject oculta a todos los objetos, cuya propiedad .Properties contiene una colección de todas las definiciones de propiedad del objeto (nombre, valor, metadatos adicionales como el tipo de propiedad, ...); p.ej:

> $objFromJson.Object1.PSObject.Properties MemberType : NoteProperty IsSettable : True IsGettable : True Value : o11 TypeNameOfValue : System.String Name : key1 IsInstance : True # ... remaining properties

La salida de la colección de las definiciones de propiedad de $objFromJson y la extracción de las propiedades de Name y Value las definiciones es un paso en la dirección correcta:

> $objFromJson.PSObject.Properties | Select-Object Name, Value Name Value ---- ----- Object1 @{key1=o11; key2=o12; key3=o13; key4=o14} Object2 @{key1=o21; key2=o22; key3=o23; key4=o24} Object3 @{key1=o31; key2=o32; key3=o33; key4=o34} Object4 @{key1=o41; key2=o42; key3=o43; key4=o44} Object5 @{key1=o51; key2=o52; key3=o53; key4=o54}

Sin embargo, debemos hacer que las propiedades .Value propiedad .Value de los objetos de salida se obtengan con valores individuales de propiedad.

La elegante respuesta de Ansgar demuestra cómo hacer eso en una sola tubería.
Permítanme complementarlo con una función de ayuda reutilizable derivada de él:

function ConvertTo-Collection($InputObject) { foreach ($obj in $InputObject) { foreach ($prop in $obj.PSObject.Properties) { $prop.Value | Select-Object @{ n=''Name''; e={ $prop.Name }}, * } } }

Con esa función en su lugar, la salida deseada ahora se puede lograr así:

ConvertTo-Collection $objFromJson | Format-Table

Para excluir una propiedad específica, como key3 :

ConvertTo-Collection $objFromJson | Select-Object -ExcludeProperty key3 | Format-Table