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"