powershellnew-object

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


Need to export overall groups info in particular OU (recursively) from Acitve Directory structure with these fields:

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

all this info I need for each OU (Groups hierarchy,recursively).

I've found several examples and tried to consolidate'em, but I'm having several troubles in output. I've coded them below in comments. This is the code for now:

    #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
             }
            }

This is the sample output (besides red mistakes with Identity in Get_ADUser commands):

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

Resulting info is gathered very slowly.How to optimize the code ?


Solution

  • Here's a version that seems to work:

    $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