在 PowerShell 中导出为 CSV 时如何指定列顺序?
Posted
技术标签:
【中文标题】在 PowerShell 中导出为 CSV 时如何指定列顺序?【英文标题】:How can I specify the column ordering when exporting to CSV in PowerShell? 【发布时间】:2017-06-24 18:13:18 【问题描述】:我正在 PowerShell 中编写一个脚本,用于从 Active Directory 中导出所有安全组及其成员。现在我想格式化 CSV 文件的输出。
代码:
$Groups = Get-ADGroup -Properties * -Filter * -SearchBase "OU=SERVICES,DC=XXXXXX,DC=XXXXX"
$Table = @()
$Record = @
"Group Name" = ""
"Name" = ""
"Username" = ""
Foreach($G In $Groups)
$Arrayofmembers = Get-ADGroupMember -identity $G -recursive | select name,samaccountname
Foreach ($Member in $Arrayofmembers)
$Record."Group Name" = $G.Name
$Record."Name" = $Member.name
$Record."UserName" = $Member.samaccountname
$objRecord = New-Object PSObject -property $Record
$Table += $objrecord
$Table | export-csv "C:\temp\SecurityGroups.csv" -NoTypeInformation
结果:
"Username","Name","Group Name"
"aman","Ani Manoukian","Commercial"
"adan","Aurelia Danneels","Commercial"
"kdeb","Kathleen De Backer","Commercial"
"TVGR","Thijs Van Grimbergen","Commercial"
"SVDE","Sofie Van den Eynde","Commercial"
现在我希望按以下顺序格式化输出:
"Group Name","Name","Username"
而不是:
"Username","Name","Group Name"
【问题讨论】:
【参考方案1】:这应该可以...
$Table |
Select-Object "Group Name", "Name", "Username" |
Export-Csv "C:\temp\SecurityGroups.csv" -NoTypeInformation
【讨论】:
当您不控制集合的创建(或不想)时,此答案也适用【参考方案2】:gvee's helpful answer 是一种实用 解决方案,可确保列按所需顺序显示,因为将属性名称传递给Select-Object
的顺序就是添加属性的顺序到生成的[pscustomobject]
实例。
然而,它效率低下,因为在$Record
被定义时可以确保所需的列顺序,而不需要一个额外的管道阶段,有效地复制结果对象:
将$Record
定义为有序哈希表,如下所示(需要PSv3+):
$Record = [ordered] @
"Group Name" = ""
"Name" = ""
"Username" = ""
这保证了稍后由New-Object PSObject -property $Record
调用创建的[pscustomobject]
实例包含的属性与在$Record
中定义的键的顺序相同。
两旁:
New-Object PSObject -property $Record
可以简化为 [pscustomobject] $Record
使用[System.Collections.ArrayList]
向其中添加元素的.Add()
实例可以更有效地处理增量构建大型数组,而不是使用带有+=
的PowerShell 内置数组,后者每次都会创建数组的副本.更好的是让 PowerShell 为您创建数组,只需在变量中捕获 foreach
循环的输出($Table = foreach ...
- 请参阅 this answer)
补充资料:
问题的根源在于常规哈希表([hashtable]
实例)以有效的不可预测顺序枚举其键(该顺序是实现细节,不保证),并且当您从哈希表创建[pscustomobject]
时,不可预测的键顺序会反映在结果对象属性的顺序中。
相比之下,在 PSv3+ 中,您可以通过在前面放置 [ordered]
关键字创建一个有序哈希表一个哈希表文字,这会产生一个 [System.Collections.Specialized.OrderedDictionary]
实例,其键是根据它们的添加顺序添加。
从有序哈希表创建 [pscustomobject]
实例,然后在结果对象的属性中保留该键顺序。
请注意,PowerShell v3+ 提供了一个方便的快捷方式,用于使用 cast 从哈希表创建 [pscustomobject]
实例;例如:
PS> [pscustomobject] @ a = 1; b = 2; c = 3 # key order is PRESERVED
a b c
- - -
1 2 3
请注意键定义顺序是如何保留的,即使未指定 [ordered]
。
换句话说:当你将一个哈希表文字直接转换为[pscustomobject]
,[ordered]
是隐含的,所以上面的等价于:
[pscustomobject] [ordered] @ a = 1; b = 2; c = 3 # [ordered] is optional
警告:此隐式排序仅适用于散列表文字直接转换为[pscustomboject]
,因此键/属性顺序不保留在以下变体中:
New-Object PSCustomObject -Property @ a = 1; b = 2; c = 3 # !! order NOT preserved
$ht = @ a = 1; b = 2; c = 3 ; [pscustomobject] $ht # !! order NOT preserved
[pscustomobject] (@ a = 1; b = 2; c = 3 ) # !! order NOT preserved, due to (...)
因此,当不将哈希表文字直接 转换为[pscustomobject]
时,请使用[ordered]
显式定义它。
【讨论】:
以上是关于在 PowerShell 中导出为 CSV 时如何指定列顺序?的主要内容,如果未能解决你的问题,请参考以下文章
在 Adobe Illustrator 画布大小问题中导出为 SVG [关闭]