Powershell Scripts

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

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"