Cuando intentamos exportar datos a otras funciones a través de la canalización, observamos un comportamiento extraño en PowerShell.
Código de ejemplo:
$Array = @() $Obj1 = [PSCustomObject]@{ Member1 = 'First' Member2 = 'Second' } $Obj2 = [PSCustomObject]@{ Member1 = 'First' Member2 = 'Second' Member3 = 'Third' } $Array = $Obj1, $Obj2 $Array | Out-GridView -Title 'Not showing Member3' $Array = $Obj2, $Obj1 $Array | Out-GridView -Title 'All members correctly displayed'
En el ejemplo anterior, puede ver que cuando el primer objeto solo contiene 2 properties
, Out-GridView
CmdLet (y otros) solo muestran 2 properties
, aunque el segundo objeto tiene 3 properties
. Sin embargo, cuando el primer objeto en la matriz tiene 3 properties
, los muestra todos correctamente.
¿Hay alguna forma de evitar esto? Porque no es posible predecir de antemano cuántas properties
habrá en un objeto y si el objeto con más properties
será el primero en la array
.
Tuve la misma experiencia una vez y creé la siguiente función ‘ Union
‘ reutilizable:
Function Union { $Union = @() $Input | ForEach { If ($Union.Count) {$_ | Get-Member | Where {!($Union[0] | Get-Member $_.Name)} | ForEach {$Union[0] | Add-Member NoteProperty $_.Name $Null}} $Union += $_ } $Union }
Uso:
$Obj1, $Obj2 | Union | Out-GridView -Title 'Showing all members'
También se supone que funciona con objetos complejos. Algunos cmdlets estándar generan múltiples tipos de objetos a la vez y, si los visualizas (por ejemplo, Out-GridView
) o los vueltas en un archivo (por ejemplo, Export-Csv
), es posible que te pierdas muchas propiedades. Tome como otro ejemplo:
Get-WmiObject -Namespace root/hp/instrumentedBIOS -Class hp_biosSetting | Union | Export-Csv ".\HPBIOS.csv"
Agregado 2014-09-19:
Quizás esto ya está entre líneas en los comentarios $Array | Select * | …
$Array | Select * | …
$Array | Select * | …
no resolverá el problema sino que seleccionará específicamente las propiedades $Array | Select Member1, Member2, Member3 | …
$Array | Select Member1, Member2, Member3 | …
$Array | Select Member1, Member2, Member3 | …
hace.
Además, aunque en la mayoría de los casos la función de Union
funcionará, existen algunas excepciones ya que solo alineará el primer objeto con el rest. Considera el siguiente objeto:
$List = @( New-Object PSObject -Property @{Id = 2} New-Object PSObject -Property @{Id = 1} New-Object PSObject -Property @{Id = 3; Name = "Test"} )
Si ExportTo-CSV
este objeto todo parece estar bien y si, por ejemplo, ExportTo-CSV
y trabajas con el archivo de export .csv
partir de ese momento, nunca tendrás ningún problema.
$List | Union Id Name -- ---- 2 1 3 Test
Todavía hay una trampa ya que solo el primer objeto está alineado. Si, por ejemplo, ordena el resultado en Id
( Id
Sort Id
) o solo las últimas 2 ( Select -Last 2
) entradas, el Name
no figura en la lista porque el segundo objeto no contiene la propiedad Name
:
$List | Union | Sort Id Id -- 1 2 3
Por lo tanto, he reescrito la función Union-Object
(Alias Union
)`):
Function Union-Object ([String[]]$Property = @()) { # Version 00.02.01, by iRon $Objects = $Input | ForEach {$_} If (!$Property) {ForEach ($Object in $Objects) {$Property += $Object.PSObject.Properties | Select -Expand Name}} $Objects | Select ([String[]]($Property | Select -Unique)) } Set-Alias Union Union-Object
Sintaxis:
$Array | Union | Out-GridView -Title 'All members correctly displayed'
Para obtener la última versión de Union-Object
, consulte: https://powersnippets.com/union-object/