List Enabled Active Directory Users and Direct Group Memberships

This example exports enabled Active Directory users and their direct group memberships to CSV. It corrects a variable-name mismatch in the earlier version that prevented the loop from processing users. Memberships listed on a user object are direct memberships; this report does not expand nested groups or include a user’s primary group.

Requirements

Run on Windows with the ActiveDirectory module and read access to the domain. Replace the Global Catalog host with one in your forest. Port 3268 is used for Global Catalog queries. The script only reads directory data and writes a CSV to the current user’s temporary folder.

Export enabled users and direct groups

$globalCatalog = "gc01.contoso.com:3268" # Replace with a GC in your forest
$outputFile = Join-Path $env:TEMP "User-Groups-$(Get-Date -Format 'yyyyMMdd-HHmmss').csv"

$users = Get-ADUser -Filter 'Enabled -eq $true' -Server $globalCatalog -Properties MemberOf, EmployeeNumber, UserPrincipalName

$groupCache = @{}
$results = foreach ($user in $users) {
    $groupNames = foreach ($groupDn in $user.MemberOf) {
        if (-not $groupCache.ContainsKey($groupDn)) {
            $groupCache[$groupDn] = Get-ADGroup -Identity $groupDn -Server $globalCatalog -Properties GroupScope, GroupCategory
        }

        $group = $groupCache[$groupDn]
        "{0} [{1}/{2}]" -f $group.Name, $group.GroupScope, $group.GroupCategory
    }

    [pscustomobject]@{
        SamAccountName = $user.SamAccountName
        Name = $user.Name
        UserPrincipalName = $user.UserPrincipalName
        EmployeeNumber = $user.EmployeeNumber
        DirectGroups = $groupNames -join "; "
    }
}

if ($results) {
    $results | Export-Csv -Path $outputFile -NoTypeInformation
    Write-Host "Exported user and group data to $outputFile"
}
else {
    Write-Host "No enabled users were returned."
}

The group cache avoids looking up the same group repeatedly. Review the exported file as directory data and store it only in an approved location. If you need nested effective membership or primary-group membership, use a separate query designed for that requirement.

See Microsoft’s documentation for Get-ADUser, Get-ADGroup, and specifying a Global Catalog server and port.