通过 Powershell 对多个 AD 对象属性进行排序

Sorting of multiple AD-object attributes via Powershell

我想从 AD 中获取计算机列表以及计算机所属的组。到目前为止相当简单:

Get-adcomputer -filter * -properties Memberof | Sort CanonicalName | select-object -Property Name, Memberof

工作正常,但问题是组(属性 Memberof 的成员)未排序,对象之间的排序不一致。

Name      Memberof                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
----      --------  
PC001     {CN=(A) Group3,OU=OU-Path,DC=domain,DC=local, CN=(A) Group1,OU=OU-Path,DC=domain,DC=local, CN=(A) Group4,OU=OU-Path,DC=domain,DC=local, CN=(A) Group2,OU=OU-Path,DC=domain,DC=local}
PC002     {CN=(A) Group4,OU=OU-Path,DC=domain,DC=local, CN=(A) Group3,OU=OU-Path,DC=domain,DC=local, CN=(A) Group2,OU=OU-Path,DC=domain,DC=local, CN=(A) Group3,OU=OU-Path,DC=domain,DC=local}
PC003     ...     

我试图根据我的 使用 -ExpandProperty MemberOf 来解决问题,例如像这样的东西:

Get-adcomputer -filter * -properties Memberof | Sort CanonicalName | select-object -Property Name -ExpandProperty MemberOf | Sort-Object -Property MemberOf

我并不感到惊讶,但没有用。以这种方式是否可能,或者我是否必须将 Name 和 MemberOf 读出到单独的变量中,然后再将它们组合起来(以及如何确保它们“对齐”)?什么是可行的方法?

我相信解决这个问题的唯一方法是完全构建一个新对象,但是除了在控制台上显示对象之外,我看不出这样做有什么意义。如果这是为了导出数据,那么这种方法毫无意义,因为 CanonicalName 是一个 string 值,而 MemberOf 是一个 array:

$computers = @(
    [pscustomobject]@{
        CanonicalName = 'somedomain.com/Computers/Computer2'
        Name          = 'Computer2'
        MemberOf      = @(
            'CN=(A) Group3,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
            'CN=(A) Group1,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
            'CN=(A) Group4,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
            'CN=(A) Group2,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
        )
    }
    [pscustomobject]@{
        CanonicalName = 'somedomain.com/Computers/Computer1'
        Name          = 'Computer1'
        MemberOf      = @(
            'CN=(A) Group3,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
            'CN=(A) Group1,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
            'CN=(A) Group4,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
            'CN=(A) Group2,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local'
        )
    }
)

$computers | Sort-Object CanonicalName | ForEach-Object {
    $_ | Select-Object Name, @{
        Name = 'MemberOf'
        Expression = { $_.MemberOf | Sort-Object }
    }
}
Name              MemberOf
----              --------
Computer1         {CN=(A) Group1,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local, CN=(A) Group2,....
Computer2         {CN=(A) Group1,OU=OU-Path1,OU=OU-Path2,DC=domain,DC=local, CN=(A) Group2,....

如果这是为了将数据导出到 CSV 等格式,那么您应该采用以下方法:

$computers | ForEach-Object {
    foreach($group in $_.MemberOf)
    {
        $cn, $ou = $group -split '(?<!\),',2
        [pscustomobject]@{
            CanonicalName = $_.CanonicalName
            Name          = $_.Name
            MemberOf      = $cn.Replace('CN=','')
            OU            = $ou
        }
    }
} | Sort-Object CanonicalName, MemberOf | Select-Object Name, MemberOf
Name      MemberOf
----      --------
computer1 (A) Group1
computer1 (A) Group2
computer1 (A) Group3
computer1 (A) Group4
computer2 (A) Group1
computer2 (A) Group2
computer2 (A) Group3
computer2 (A) Group4