在 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 时如何指定列顺序?的主要内容,如果未能解决你的问题,请参考以下文章

在 jQuery 中导出为 csv

在 Adob​​e Illustrator 画布大小问题中导出为 SVG [关闭]

在 React-Table 中导出为 PDF

捕获视频帧,然后在 HTML5 中导出为位图

SSIS 2008 - 在平面文件目标中导出为指数值的浮点值

arcGIS中属性表怎么导出到EXCEL里