powershell - 在 PowerShell 中导出为 CSV 时如何指定列顺序?

我正在 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"

现在我希望按以下顺序格式化输出:

“组名”、“名称”、“用户名”

而不是: "用户名","姓名","组名"

最佳答案

gvee's helpful answer是一种实用解决方案,可确保列以所需的顺序出现,因为您将属性名称传递给 Select-Object是将属性添加到结果 [pscustomobject] 中的顺序实例。

然而,它效率低下,因为$Record 时可以确保所需的列顺序已定义,不需要有效复制结果对象的额外管道阶段:

定义 $Record作为有序哈希表如下(需要PSv3+):

$Record = [ordered] @{
    "Group Name" = ""
    "Name" = ""
    "Username" = ""
}

这保证了 [pscustomobject]稍后由 New-Object PSObject -property $Record 创建的实例调用包含的属性与 $Record 中定义的键的顺序相同。 .

两旁:

  • New-Object PSObject -property $Record可以简化为 [pscustomobject] $Record
  • 使用 [System.Collections.ArrayList] 可以更有效地以增量方式构建大型数组。使用 .Add() 添加元素的实例而不是使用 PowerShell 的内置数组和 += ,它每次都会创建一个数组的副本。更好的是让 PowerShell 为您创建数组,只需捕获 foreach 的输出即可。在变量中循环($Table = foreach ... - 见 this answer)

补充资料:

问题的根源在于常规哈希表([hashtable] 实例)以有效的不可预测顺序枚举它们的键(顺序是实现细节,不保证),当您创建 [pscustomobject]从哈希表中,不可预测的键顺序反射(reflect)在结果对象属性的顺序中。

相比之下,在 PSv3+ 中,您可以通过放置 [ordered]创建一个有序哈希表关键字 在哈希表文字之前,这会导致 [System.Collections.Specialized.OrderedDictionary] 实例,其键是根据它们的添加顺序添加
创建 [pscustomobject]然后,来自有序哈希表的实例将该键排序保留在结果对象的属性中。

请注意,PowerShell v3+ 提供了一个方便的快捷方式来创建 [pscustomobject]使用 cast 的哈希表中的实例;例如:

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] 定义它明确的。

https://stackoverflow.com/questions/42090900/

相关文章:

sql - 总是在 SQL 中显示小数位?

html - 在 Rails 中,如何在文本区域中允许一些 html?

netbeans - 更改netbeans中自动突出显示的变量名的突出显示颜色?

perl - 在 Perl 中处理非常大的数字时,如何禁用科学记数法?

php - 保持我的 PHP 漂亮

javascript - 使用纯 JavaScript 将电话号码格式化为用户类型

formatting - 好的评论用例

javascript - 不允许在 textarea 中换行

c# - 我应该使用 ToString() 还是 GetDateTimeFormats() 来格式化

python - 在列表上迭代格式字符串