繁体   English   中英

将带有字符串键和 PSObject 值的复杂哈希表导出到.csv [PowerShell]

[英]Exporting complex Hashtable with string key and PSObject value to .csv [PowerShell]

我有一个名为$userTable的用户哈希表,其格式为:。

<key = string, value = PSObject>

对象被添加到哈希表中,如下所示:

$userTable = @{}

$id="1056456"
$user = New-Object PSObject -Property @{
    Name="Test Name"
    Email="Test Email"
    Systems = New-Object System.Collections.ArrayList
}

$system1 = New-Object PSObject -Property @{
   Name="System 1"
   Admin=$true
   Status="Active"
}

$system2 = New-Object PSObject -Property @{
   Name="System 2"
   Admin=$false
   Status="Inactive"
}

$user.Systems.Add($system1) | Out-Null
$user.Systems.Add($system2) | Out-Null

$userTable.Add($id, $user)

因此,对于$userTable中的每个条目,都有一个名称、一个 email 以及与该用户关联的系统列表。

我想要做的是将此数据导出到.csv ,使其采用以下形式:

ID, Name, Email, System Count, System1 Name, System1 Admin, System1 Status, System2 Name, etc..

每个用户可能有超过 2 个系统。

我无法理解如何将其导出到 a.csv 文件。

任何帮助将不胜感激,谢谢。

我正在考虑使用以下内容:

$userTable.GetEnumerator() |
Select-Object -Property @{N='ID';           E={$_.Key}},
                        @{N='Name';         E={$_.Value.Name}},
                        @{N='Email';        E={$_.Value.Email}},
                        @{N='System Count'; E={$_.Value.Systems.Count}} |
    Export-Csv -NoTypeInformation -Path C:\Documents\test.csv

但这不包括系统阵列列表(尚未)

我必须同意@MathiasR.Jessen 的评论。 这在SO上出现了很多。 CSV 是一种方便的格式,通常是持久存储和/或在程序或系统之间中继信息的首选。 然而,它是扁平的,因此对于丰富的层次和/或复杂的对象来说是一个非常糟糕的模拟。

如果对象只有 1 级深度,例如,如果.Systems本身是一个简单数组,则可以对字段进行子分隔。 一个很好的例子是 MS Exchange 邮件跟踪日志,它虽然用“,”分隔,但在“;”上对收件人字段进行子分隔。 但是,go 不止于此。

简而言之,您为绕过 CSV 格式的限制而尝试做的任何事情最终都会增加代码的复杂性。 您将不得不费力地编写 CSV 就这样...然后再费力将其重新导入其他地方...

JSON 和 CliXML 是您的选择。 它们都非常适合存储甚至是复杂对象的基于文本的表示。 此类示例可能类似于:

$userTable.GetEnumerator() |
Select-Object -Property @{N='ID';           E={$_.Key}},
                        @{N='Name';         E={$_.Value.Name}},
                        @{N='Email';        E={$_.Value.Email}},
                        @{N='System Count'; E={$_.Value.Systems.Count}},
                        @{N='Systems';      E={$User.Systems}} |
ConvertTo-Json | 
Add-Content -Path "C:\temp\JSONOutput.json"

由于我们没有更多的代码体,我不确定“系统”属性是否被适当地填充。 但是,您只是将属性系统设置为具有 ArrayList 的值,其中的元素是其他对象。

JSON 显然非常流行,但 CliXML 更原生于 PowerShell。 CliXML 替代方案如下所示:

$userTable.GetEnumerator() |
Select-Object -Property @{N='ID';           E={$_.Key}},
                        @{N='Name';         E={$_.Value.Name}},
                        @{N='Email';        E={$_.Value.Email}},
                        @{N='System Count'; E={$_.Value.Systems.Count}},
                        @{N='Systems';      E={$User.Systems}} |
Export-Clixml c:\temp\CliXML_Export.xml

而且,要在其他地方使用数据,分别看起来像:

# For JSON:
$SomeVar = (Get-Content "C:\temp\JSONOutput.json") | ConvertFrom-Json

# For CliXml:
$SomeVar = Import-CliXml c:\temp\CliXML_Export.xml

注意:Json 示例中Get-Content周围的(...) 我相信这是 PowerShell 5.1 所要求的。 尽管我认为这已在 7+ 中得到修复,但您可以在其中删除括号。 我不确定这个限制是否在 6.x 中。

注意:通常在如上所述序列化对象时,方法将被剥离。 对于 CliXml,它与 PowerShell 远程处理中用于通过线路序列化对象的格式相同,具有相同的限制。 也就是说,出于此处演示的目的,这些格式通常具有足够的保真度以供后续使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM