我有一个PSObject [],我们可以调用$DeviceFW
,它有两个我关心的孩子:Bay
(字符串)和Components
(Object [])这基本上只是一个哈希表数组。我要做的是将组件导出为CSV,每行列出相应的Bay。
$DeviceFW.Components | Export-Csv "FW.csv" -NoTypeInformation
几乎是完美的,除了它缺少Bay列和信息。
$DeviceFW | Select Bay,Components | Export-Csv "FW.csv" -NoTypeInformation
包含Bay列和正确的信息,但Components只在单个列中显示为“System.Management.Automation.PSObject []”
我不知何故需要一种方法来导出扩展的组件,同时包括相应托架的列。我想到的是从组件选择管道中解决父级其他属性(Bay)的一种神奇方法,例如:#$DeviceFW.Components | Select-Object @{Name='Bay';Expression={$_.Parent.Bay}},*
。我对PowerShell很新,所以我确信这完全是关闭的。也许我应该用循环来解决它,并放弃管道?
关于我所追求的一个例子,下面......
$DeviceFW:
Bay: 1
Components: {@{Name=ROM;Ver=A;ISO=A},@{Name=PWR;Ver=B;ISO=B}}
Bay: 2
Components: {@{Name=ROM;Ver=C;ISO=C},@{Name=PWR;Ver=D;ISO=D}}
...应输出为:
Bay | Name | Ver | ISO
-----------------------
1 | ROM | A | A
-----------------------
1 | PWR | B | B
-----------------------
2 | ROM | C | C
-----------------------
2 | PWR | D | D
答案 0 :(得分:3)
$DeviceFW | ForEach-Object{
$props = @{}
$props.bay = $_.Bay
$_.Components | ForEach-Object{
$_.GetEnumerator() | ForEach-Object{
$props.($_.Name) = $_.Value
}
New-Object -TypeName PsCustomObject -Property $props
}
} | Select-Object Bay,Name,Ver,ISO | Export-Csv "FW.csv" -NoTypeInformation
使用上面的代码创建一个具有示例属性的对象。我试图让它成为一个单行,但它变得越来越复杂。
对于每一个$DeviceFW
我构建一个新的propery哈希表,首先填充Bay#。获取组件并将它们传递给每个循环,以将它们分解为您拥有的两个哈希表。每个哈希表都枚举它们以作为对象进行访问,因此我们可以使用每个组件的名称和值对填充$props
。每个组件都通过管道发送,其Bay编号作为参数。使用select语句强制执行字段顺序并发送到Export-Csv
。这可以通过获取组件并使用Add-Member
添加Bay来简化。
更短的东西
$DeviceFW | ForEach-Object{
$Bay = $_.Bay
$_.Components | ForEach-Object{
New-Object PSObject -property $_ | Add-Member -MemberType NoteProperty -Name "Bay" -Value $Bay -PassThru
}
} | Select-Object Bay,Name,Ver,ISO | Export-Csv "FW.csv" -NoTypeInformation
我很傻,试图重新发明轮子。由于每个Component都已经是一个哈希表,我不需要重新创建它。获取每个组件并使用它创建一个对象。获取该对象并为当前托架添加成员。
导出前输出
我的两个例子都是一样的。这应该很好地导出到csv。
Bay Name Ver ISO
--- ---- --- ---
1 ROM A A
1 PWR B B
2 ROM C C
2 PWR D D
FYI
我使用以下内容为上面的代码创建了我的样本对象。
$DeviceFW = @()
$DeviceFW += [pscustomobject]@{
Bay = 1
Components = @{Name="ROM";Ver="A";ISO="A"},@{Name="PWR";Ver="B";ISO="B"}
}
$DeviceFW += [pscustomobject]@{
Bay = 2
Components = @{Name="ROM";Ver="C";ISO="C"},@{Name="PWR";Ver="D";ISO="D"}
}
答案 1 :(得分:3)
从您给出的示例中,我按如下方式构建了数组/对象:
$DeviceFW = @(
[PSCustomObject]@{
'Bay' = '1'
'Components'=@(
[pscustomobject]@{'Name'='ROM';'Ver'='A';'ISO'='A'},
[pscustomobject]@{'Name'='PWR';'Ver'='B';'ISO'='B'}
)},
[PSCustomObject]@{
'Bay' = '2'
'Components'=@(
[pscustomobject]@{'Name'='ROM';'Ver'='C';'ISO'='C'},
[pscustomobject]@{'Name'='PWR';'Ver'='D';'ISO'='D'}
)}
)
这是一个对象数组,每个对象包含两个属性,Bay
是一个字符串,Components
是一个对象数组。 Components
中的每个对象都包含三个属性Name
,Ver
和ISO
,每个属性都是一个字符串。当我做$DeviceFW|FL
时,我得到了:
Bay : 1
Components : {@{Name=ROM; Ver=A; ISO=A}, @{Name=PWR; Ver=B; ISO=B}}
Bay : 2
Components : {@{Name=ROM; Ver=C; ISO=C}, @{Name=PWR; Ver=D; ISO=D}}
到目前为止,这与您的示例匹配。为了得到你想要的CSV,我会把它放在ForEach循环中:
Foreach($record in $DeviceFW){
$record.components|select @{l='Bay';e={$record.bay}},*|Export-Csv c:\temp\output.csv -NoTypeInformation -Append
}
输出文件:
"Bay","Name","Ver","ISO"
"1","ROM","A","A"
"1","PWR","B","B"
"2","ROM","C","C"
"2","PWR","D","D"
答案 2 :(得分:0)
我喜欢上面给出的答案,他们都帮助我理解如何实现这一目标。我尝试将它们组合起来创建一个根据Matt的答案只使用一行的解决方案,但根据TheMadTechnician的答案,它稍微简单一些。使用在TheMadTechnician的答案中创建的$ DeviceFW对象(我更喜欢这个,因为组件是一个对象数组,而不是像Matt的答案中的哈希表数组,因此更典型的对象是使用PowerShell时每天都会遇到这种情况。我最终得到了以下解决方案。
$DeviceFW|ForEach-Object{$Bay = $_.Bay;$_.components|ForEach-Object{$_|Select-Object *,@{label='Bay';expression={$Bay}}}}|Export-Csv "FW.csv" -NoTypeInformation