访问管道中的父属性

时间:2014-10-20 20:36:13

标签: powershell csv

我有一个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

3 个答案:

答案 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中的每个对象都包含三个属性NameVerISO,每个属性都是一个字符串。当我做$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