AD Group-Based Scripts
Active Directory groups are a fundamental part of managing permissions, access, and organizational hierarchy. These scripts help administrators report, audit, and manage AD groups efficiently.
On this page, you will find scripts categorized by common use cases, including listing groups, checking membership, nested groups, inactive groups, and groups by OU. Each script can be run directly in PowerShell and exported to CSV for reporting purposes.
- List all groups – export all security and distribution groups.
- Group membership report – see all members in a specific group.
- Nested group membership – expand groups that contain other groups.
- Groups by OU – organize and report groups by their organizational unit.
- Inactive groups – detect groups with no members or no activity.
List all Groups
Get-ADGroup -Filter * -Properties GroupCategory, GroupScope | Select Name,SamAccountName,GroupCategory,GroupScope | Export-Csv "C:\Reports\AD_AllGroups.csv" -NoTypeInformation
Group membership report
Get-ADGroupMember -Identity "YourGroupName" | Select-Object Name,SamAccountName,ObjectClass | Export-Csv "C:\Reports\YourGroupName_Members.csv" -NoTypeInformation
Nested group membership
# Set the group name you want to report $GroupName = "YourGroupName" # Output CSV paths $UsersCsvPath = "C:\Reports\$GroupName_NestedUsers.csv" $ComputersCsvPath = "C:\Reports\$GroupName_ComputersInGroup.csv" # Create function to recursively get users function Get-NestedGroupMembers { param ($Group) Get-ADGroupMember -Identity $Group | ForEach-Object { switch ($_.objectClass) { "user" { $_ } # Include users "group" { Get-NestedGroupMembers $_.SamAccountName } # Recurse into nested groups "computer" { $_ } # Optional: collect computers separately } } } # Get all members recursively $allMembers = Get-NestedGroupMembers $GroupName # Separate users and computers $users = $allMembers | Where-Object { $_.objectClass -eq "user" } $computers = $allMembers | Where-Object { $_.objectClass -eq "computer" } # Export users $users | Select-Object Name, SamAccountName, ObjectClass | Export-Csv $UsersCsvPath -NoTypeInformation Write-Host "Nested users exported to $UsersCsvPath" # Export computers (if any) if ($computers) { $computers | Select-Object Name, SamAccountName, ObjectClass | Export-Csv $ComputersCsvPath -NoTypeInformation Write-Host "Computers in group exported to $ComputersCsvPath" } else { Write-Host "No computers found in the group." }
Groups by OU
# Import Active Directory module Import-Module ActiveDirectory # Output CSV path $exportPath = "C:\Reports\AD_Groups_By_OU_$(Get-Date -Format yyyyMMdd).csv" # Get all groups with their DistinguishedName (to find OU) Get-ADGroup -Filter * -Properties DistinguishedName, GroupCategory, GroupScope | Select-Object Name, SamAccountName, GroupCategory, GroupScope, @{Name="OU";Expression={ ($_.DistinguishedName -split ',DC=')[0] -replace '^CN=.*?,OU=', '' }} | Export-Csv -Path $exportPath -NoTypeInformation Write-Host "Groups by OU exported to $exportPath"
Inactive groups
Import-Module ActiveDirectory # Get all groups with no members Get-ADGroup -Filter * | ForEach-Object { $members = Get-ADGroupMember -Identity $_ -ErrorAction SilentlyContinue if (-not $members) { [PSCustomObject]@{ GroupName = $_.Name SamAccountName = $_.SamAccountName DistinguishedName = $_.DistinguishedName } } } | Export-Csv "C:\Reports\Empty_AD_Groups.csv" -NoTypeInformation Write-Host "Empty groups exported to C:\Reports\Empty_AD_Groups.csv"
Import-Module ActiveDirectory # Define inactivity threshold (e.g., 365 days) $daysInactive = 365 $cutoffDate = (Get-Date).AddDays(-$daysInactive) # Get groups not modified in the last year Get-ADGroup -Filter * -Properties whenChanged | Where-Object { $_.whenChanged -lt $cutoffDate } | Select-Object Name, SamAccountName, whenChanged | Export-Csv "C:\Reports\Inactive_AD_Groups.csv" -NoTypeInformation Write-Host "Inactive groups report exported to C:\Reports\Inactive_AD_Groups.csv"