tossaire
tossaire

Reputation: 3

Speed up AD Group/Membership Report in Powershell

So I'm pretty new to Powershell scripting and I was looking for ways to go through an entire forest and select only groups with specific string included in their AD group name and then to pull the full member list for each group and then include their AD account status/object class as well. This is what I'm using currently... any help would be appreciated as this currently runs slower than.. well it runs really slow.

$OutputFileName = "Test File.csv"
$Data=@()

if (Test-Path $OutputFileName) {
  Remove-Item $OutputFileName
}
$Tab = [char]9
foreach($Domain in Get-ADForest | select -ExpandProperty domains){
    Foreach($ADGroup in get-adgroup -Filter {name -like "Test*"} -server $Domain){
        Foreach($Member in Get-ADGroupMember -Identity $ADGroup -server $Domain){
        
        $Data = Get-ADUser -Identity $Member -Properties enabled | 
            Select-Object @{Label = "AD Group";Expression = {$ADGroup.name}},  
            @{Name = "NTID";Expression = {$Member.samaccountname}},
            @{Name = "Object Class";Expression = {$Member.objectclass}},
            @{Name = "Account Status";Expression = {if (($_.Enabled -eq 'TRUE')  ) {'Enabled'} Else {'Disabled'}}}
            

$Data | Export-Csv -Path c:\users\xxxxx\Test File.csv -NoTypeInformation -Append 
        }
    }
}

Upvotes: 0

Views: 1306

Answers (1)

Cpt.Whale
Cpt.Whale

Reputation: 5341

Get-ADGroupMember is an awfully inefficient cmdlet for a few reasons, so instead of this:

Foreach($ADGroup in Get-ADGroup -Filter {name -like "Test*"} -server $Domain){
  Foreach($Member in Get-ADGroupMember -Identity $ADGroup -server $Domain){
    $Data = Get-ADUser -Identity $Member -Properties enabled |
    ...

Let's cut out Get-ADGroupMember to save many, many AD lookups:

# Save results to a single list object
$Result = @()

Foreach($Domain in Get-ADForest | select -ExpandProperty domains){
  Foreach ($ADGroup in (Get-ADGroup -Filter 'name -like "Test*"' -Server $Domain)) { 
    # Cut out Get-ADGroupMember --
    Foreach ($Member in (Get-ADObject -Filter "MemberOf -EQ '$($ADGroup.DistinguishedName)'" -Properties userAccountControl,samaccountname -Server $Domain)) {
      $Data = '' |
        Select-Object @{Label = "AD Group";Expression = {$ADGroup.name}},  
          @{Name = "NTID";Expression = {$Member.samaccountname}},
          @{Name = "Object Class";Expression = {$Member.objectclass}},
          @{Name = "Account Status";Expression = {
            if (($Member.userAccountControl -band 2) -eq 2 ) {'Disabled'} 
            Else {'Enabled'}
          }}
      $Result += $Data
    }
  }
}

# Do a single export.
$Result | Export-Csv -Path c:\users\xxxxx\Test File.csv -NoTypeInformation -Append 

This example takes about 1/100th of the time on my machine to return 900 users

Upvotes: 1

Related Questions