PS 导出组中的特定字段以及用户和用户属性的总和

PS export specific fields from groups and sum of users and user attributes

需要从具有以下字段的 Acitve Directory 结构导出整体组信息,尤其是 OU(递归):

OU | Groupname | GroupCategory | GroupScope | GroupMemberOf | GroupMembers (other groups,not users) | TotalUsers (if any) | UsersEnabled | Usersdisabled | UsersWithStalePass | UsersWithNonexpirePass

每个 OU(组层次结构,递归)我需要的所有这些信息。

我找到了几个示例并尝试合并它们,但我在输出时遇到了一些问题。我在下面的评论中对它们进行了编码。 这是现在的代码:

    #searchbase OU
    $OU="OU=Groups,OU=OUNAME,DC=DCNAME2,DC=DCNAME,DC=domain"

    $group = Get-ADGroup -filter * -Properties *
    $allou = (Get-ADObject -Filter {ObjectClass -eq "organizationalUnit"} -SearchBase $OU).DistinguishedName

    #list all sub OUs
    Foreach($ou in $allou){
    $LIST = Get-ADObject -LDAPFilter "(objectClass=group)" -SearchBase $OU -SearchScope OneLevel

    #begin work with each OU
    $LIST | ForEach-Object {
            $users=Get-ADGroupMember $_.DistinguishedName | Where ObjectClass -eq "user"
            $total=($users | measure-object).count #counts right
            $Enabled=($users | where {$_.Enabled} | Measure-Object).count #always shows zero (0)
            $Disabled=$total-$Enabled
            $NonExpirePasses=(Get-ADUser -Identity $_.DistinguishedName | where {$_.PasswordNeverExpires -ne $true} | Measure-Object).count #doesn't work
#this variant won't work either: $NonExpirePasses=($users | where {$_.PasswordNeverExpires -ne $true} | Measure-Object).count
            $PassesOver90d=($users | where {$_.PasswordLastSet -lt (Get-Date).AddDays(-10)} | Measure-Object).count #the same - always shows 0
#this variant won't work either: $PassesOver90d=(Get-ADUser $_.DistinguishedName | where {$_.PasswordLastSet -lt (Get-Date).AddDays(-90)} | Measure-Object).count
            $GroupCategory=Get-ADGroup $_.DistinguishedName | Select-Object GroupCategory
            $GroupScope=Get-ADGroup $_.DistinguishedName | Select-Object GroupScope
            $InGroups=(($_.MemberOf | %{(Get-ADGroup $_).sAMAccountName}).count -join ";")
            #consolidate info in new object

    New-Object psobject -Property @{
        OU=$OU;
        GroupName=$_.Name;
        GroupCategory=$GroupCategory;
        GroupScope=$GroupScope; #<<<always gives "@{GroupCategory=Security}' or @{GroupCategory=Distribution} format, and i need simple 'Security'/'Distribution'
        InGroups=$InGroups; #<<<always 0
        TotalUsers=$Total;
        Enabled=$Enabled; #<<<always 0
        Disabled=$Disabled;
        PassesOver90d=$PassesOver90d; #<<<always 0
        NonExpirePasses=$NonExpirePasses} | #<<<even doesn't shown (no 0),no info

    #sorted output, finish
       Select OU,GroupName,GroupCategory,GroupScope,InGroups,TotalUsers,Enabled,Disabled,NonExpirePasses,PassesOver90d
             }
            }

这是示例输出(除了 Get_ADUser 命令中带有 Identity 的红色错误):

OU              : OU=SD,OU=Distribution Groups,OU=Groups,OU=OUNAME,DC=DCNAME2,DC=DCNAME,DC=domain
GroupName       : BT23_USERS
GroupCategory   : @{GroupCategory=Security}
GroupScope      : @{GroupScope=Universal}
TotalUsers      : 15
Enabled         : 0
Disabled        : 15
NonExpirePasses :
PassesOver90d   : 0

收集结果信息非常 slowly.How 以优化代码?

这是一个似乎有效的版本:

$rootOU="OU=Groups,OU=OUNAME,DC=DCNAME2,DC=DCNAME,DC=domain"

$everyOU = (Get-ADObject -Filter {ObjectClass -eq "organizationalUnit"} -SearchBase $rootOU)

$everyOU | ForEach-Object {
    Get-ADGroup -Filter {Name -like "*"} -SearchBase $_.DistinguishedName -SearchScope OneLevel -Properties * |
            ForEach-Object {
                $users = Get-ADGroupMember $_.DistinguishedName | 
                            Where ObjectClass -eq "user" | ForEach-Object {Get-ADUser $_.SamAccountName -Property PasswordLastSet, PasswordNeverExpires}

                $total = @($users).Count
                $enabled = ($users | Where-Object Enabled -eq $true | Measure-Object).Count
                $disabled = $total - $enabled
                $NonExpirePasses = @($users | Where-Object PasswordNeverExpires -ne $true).Count
                $PassesOver90d = @($users | Where-Object PasswordLastSet -lt (Get-Date).AddDays(-10)).Count
                $GroupCategory = Get-ADGroup $_.DistinguishedName | Select-Object GroupCategory
                $GroupScope = Get-ADGroup $_.DistinguishedName | Select-Object GroupScope
                $InGroups = ($_.MemberOf).Count

                [PsCustomObject]@{
                    OU=$_.DistinguishedName
                    GroupName=$_.Name
                    GroupCategory=$GroupCategory.GroupCategory
                    GroupScope=$GroupScope.GroupScope
                    InGroups=$InGroups
                    TotalUsers=$Total
                    Enabled=$Enabled
                    Disabled=$Disabled
                    PassesOver90d=$PassesOver90d
                    NonExpirePasses=$NonExpirePasses
                }
        }
    } | Format-Table GroupName,GroupCategory,GroupScope,InGroups,TotalUsers,Enabled,Disabled,PassesOver90d,NonExpirePasses,OU -AutoSize