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

Posted

技术标签:

【中文标题】通过 Powershell 对多个 AD 对象属性进行排序【英文标题】:Sorting of multiple AD-object attributes via Powershell 【发布时间】:2022-01-24 03:05:27 【问题描述】:

我想从 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     ...     

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

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

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

【问题讨论】:

CanonicalName 是 1 个元素,MemberOf 是一个数组,这样排序对象的目的是什么? @SantiagoSquarzon 用于手动比较,如果未对组进行排序,则无法进行,请注意,我不使用 CanonicalName 作为输出,它仅用于对列表进行排序 附带说明,是的,我确实使用| Out-File "C:\TEMP\AD_export.txt" -Width 2000 将其输出到文件中,但这只是为了避免像在控制台中那样剪切组列表。 【参考方案1】:

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

$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

【讨论】:

很好的回答,谢谢,我更正了您回答中的“误解”(请参阅​​我对您的回答对我的问题的评论)。感谢您提供的扩展解决方案来创建一个可能是我的下一个问题的单个列表(没有子列表)。 作为后续问题,如果可能的话,是否可以过滤掉 OU 和 DC 信息 CN=,所以在 MemberOf 列下剩下的就是组的名称 @987654330 @?但也许最好为此写一个单独的问题。 @Albin 看到我的更新,您可以拆分 dstinguished 名称以获得组的常用名称。如果有用,请考虑接受答案。 太好了,谢谢,据我了解,OU = $ou 对于我的特定输出不是必需的,对吧? (但如果您决定需要再次输出 OU,它可能会派上用场) @Albin 没错,如果这是一份报告,我觉得它应该在那里。您最有可能需要该组的 OU 的引用,如果没有它,如果您有重复的名称,您将不知道哪个组是哪个。

以上是关于通过 Powershell 对多个 AD 对象属性进行排序的主要内容,如果未能解决你的问题,请参考以下文章

PowerShell部署Server2016AD服务

PowerShell部署Server2016AD服务

AD属性修改 office 365 delivery management 设定

PowerShell Active Directory列出所有多值属性

AD用户属性对照表

Powershell 修改用户配置文件