Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 将带有字符串键和PSObject值的复杂哈希表导出到.csv[PowerShell]_Windows_Powershell_Scripting_Powershell 4.0 - Fatal编程技术网

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

Windows 将带有字符串键和PSObject值的复杂哈希表导出到.csv[PowerShell],windows,powershell,scripting,powershell-4.0,Windows,Powershell,Scripting,Powershell 4.0,我有一个名为$userTable的用户哈希表,其形式为: 对象被添加到哈希表中,如下所示: $userTable = @{} $id="1056456" $user = New-Object PSObject -Property @{ Name="Test Name" Email="Test Email" Systems = New-Object System.Collections.ArrayList }

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

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

$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
中的每个条目,都有一个名称、一封电子邮件和一个与该用户关联的系统列表

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

ID, Name, Email, System Count, System1 Name, System1 Admin, System1 Status, System2 Name, etc..
每个用户可能有2个以上的系统

我无法理解如何将其导出为.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的评论。这件事经常发生。CSV是一种方便的格式,通常是持久存储和/或在程序或系统之间传递信息的首选格式。然而,它是扁平的,因此对于丰富的层次结构和/或复杂对象来说是一个相当糟糕的模拟

例如,如果对象只有1层深,如果
.Systems
本身是一个简单数组,则可以对字段进行细分。这方面的一个很好的例子是MS Exchange邮件跟踪日志,它虽然用“;”分隔,但对“;”上的收件人字段进行了子分隔。然而,它并没有走得更远

简而言之,任何试图绕过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"
# For JSON:
$SomeVar = (Get-Content "C:\temp\JSONOutput.json") | ConvertFrom-Json

# For CliXml:
$SomeVar = Import-CliXml c:\temp\CliXML_Export.xml
由于我们没有更多的代码,我不确定是否正确填充了“Systems”属性。但是,您只需将属性系统设置为具有一个值,该值是一个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
并且,在其他地方使用这些数据,分别如下所示:

$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"
# 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+中得到了修复,在这里你可以直接删除paren。我不确定这个限制是否在6.x中


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

我必须同意@MathiasR.Jessen的评论。这件事经常发生。CSV是一种方便的格式,通常是持久存储和/或在程序或系统之间传递信息的首选格式。然而,它是扁平的,因此对于丰富的层次结构和/或复杂对象来说是一个相当糟糕的模拟

例如,如果对象只有1层深,如果
.Systems
本身是一个简单数组,则可以对字段进行细分。这方面的一个很好的例子是MS Exchange邮件跟踪日志,它虽然用“;”分隔,但对“;”上的收件人字段进行了子分隔。然而,它并没有走得更远

简而言之,任何试图绕过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"
# For JSON:
$SomeVar = (Get-Content "C:\temp\JSONOutput.json") | ConvertFrom-Json

# For CliXml:
$SomeVar = Import-CliXml c:\temp\CliXML_Export.xml
由于我们没有更多的代码,我不确定是否正确填充了“Systems”属性。但是,您只需将属性系统设置为具有一个值,该值是一个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
并且,在其他地方使用这些数据,分别如下所示:

$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"
# 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+中得到了修复,在这里你可以直接删除paren。我不确定这个限制是否在6.x中


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

这是否回答了您的问题:?因此,如果有100个系统连接到其中一个对象,您希望CSV中有300多个列?确实不想导出为分层格式(如XML)?这是否回答了您的问题:?因此,如果有100个系统连接到其中一个对象,您希望CSV中有300多个列?确实不想导出为层次结构格式(如XML)吗?彻底且有用。谢谢你的建议。我把重点放在.csv上,因为下游任务(以及下游人员)似乎更喜欢我工作的地方,但我同意,这些文件格式更适合该任务。彻底且有用。谢谢你的建议。我把重点放在了.csv上,因为下游任务(以及下游人员)似乎更喜欢我工作的地方,但我同意,这些文件格式更适合这个任务。