How to Export AD Group Members with PowerShell

Getting all group members of your AD Groups can be a daunting task. You will need to open the groups and scroll through the list of users. A better option is to export the AD Group members with PowerShell.

With PowerShell, we can easily select or find all groups, and export the members to a CSV file or view them directly in the console.

In this article, we are going to export the AD Group Members with PowerShell. At the end of the article, you will find a free script that exports all or selected groups and their members.

Requirements

To export the Active Directory Group members we are going to use the Get-ADGroupMember cmdlet. You will need to make sure that you have installed the PowerShell Active Directory module before you proceed. This module is installed by default on Domain Controllers. You can install it with the following PowerShell command on Windows 10/11:

Add-WindowsCapability –online –Name “Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0”

Export AD Group Members

To export the group members of an Active Directory group we at least need to know the group name. If you have the name of the group, then you can simply export all members of the group to a CSV file with the Export-CSV cmdlet like so:

# Export all members of the group SG_M365_E3
Get-ADGroupMember -Identity 'SG_M365_E3' | Export-Csv -path c:\temp\groupmembers.csv -Notypeinformation

This will export the default attributes of the users to a CSV file:

  • distinguishedName
  • Name
  • objectClass
  • objectGUID
  • SamAccountName
  • SID

As you can see, this is often not the information that you are looking for. We could use the Select statement to select only the names of the users, but you may also want to know their job title or department for example.

Another problem is nested groups. As you can see in the example below, the group management is also a member of the selected group. You probably also want to include the members from the nested groups in your results.

export ad group members

To get the members of the nested groups, we can use the -recursive parameter. With the parameter, the cmdlet will also show the AD group members of the nested group in the results.

For the user details, we will need to pipe the Get-ADUser cmdlet behind it. This allows us to select and include more user properties in our export.

Using Get-ADUser cmdlet

The examples above are great when you have a small or medium environment and only want to view the users from a particular group. But for large environments, with more than 1000 users in a group, there is a better (faster) method.

As mentioned, when retrieving users you often need more details than only their name. Getting first all the distinguished names from the group and then looking up users, and maybe even applying a filter, can take a long time.

A better option in these cases is to use the Get-ADUser cmdlet and filter them on the memberOf attribute. For this, we will need to know the groups’ distinguished name, and we will do a recursive match.

$dn = (Get-ADGroup -Identity 'SG_M365_E3').distinguishedName
Get-ADUser -Filter "$filter memberOf -recursivematch '$($dn)'"

The advantage of this method is that you also get all the users from the nested groups. As mentioned, we can use additional filters on the Get-ADUser cmdlet, like selecting only the active users.

Export Ad Group Members Script

I created a versatile script to export the AD Group Members to a CSV file. The script allows you to export the members from multiple groups at once. The results are stored in a CSV file per group. I will walk you through the script briefly below. You can download the complete script here from my GitHub repository.

In the script, I added three options to select the group(s) to export the users from:

  • groupName – You can enter the group name or multiple group names by separating them with a comma.
  • searchBase – This allows you to export the members from all groups in a particular OU. You can also specify multiple OUs by separating them with a comma.
  • All Groups – If you don’t specify a group name or search base, then all groups are exported.

I have also added a filter that allows you to include only enabled or disabled user’s accounts. By default, it will export both.

export ad group members script
Export AD Group Members script result

In the script, you will find a couple of functions. The Get-Users function will collect the users from the groups. I have added a couple of properties to retrieve, you can modify the list to your needs.

<#
.SYNOPSIS
  Get all AD members from an AD Group
.DESCRIPTION
  This script collects all Active Directory users from a specific group or multiple groups and exports
  the users with some attributes to a CSV file per AD Group.
.OUTPUTS
  CSV or console with Active Directory Users
.NOTES
  Version:        1.0
  Author:         R. Mens
  Creation Date:  25 jan 2024
  Purpose/Change: Init
#>

param(
  [Parameter(
    Mandatory = $false,
    HelpMessage = "Enter the group name or multiple separated with a comma"
    )]
  [string[]]$groupName,

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Enter the searchbase between quotes or multiple separated with a comma"
    )]
  [string[]]$searchBase,

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Get accounts that are enabled, disabled or both"
  )]
    [ValidateSet("true", "false", "both")]
  [string]$enabled = "both",

  [Parameter(
    Mandatory = $false,
    HelpMessage = "Enter path to save the CSV file"
  )]
  [string]$CSVpath
)

Function Get-Users{
  param(
    [Parameter(Mandatory = $true)]
    $dn
  )
  # Set the properties to retrieve
  $properties = @(
    'name',
    'userprincipalname',
    'mail',
    'title',
    'enabled',
    'department',
    'lastlogondate'
  )

  # Get enabled, disabled or both users
  switch ($enabled) {
    "true" {$filter = "enabled -eq 'true' -and"}
    "false" {$filter = "enabled -eq 'false' -and"}
    "both" {$filter = ""}
  }

  # Return the users from the group
  Get-ADUser -Filter "$filter memberOf -recursivematch '$($dn)'" -Properties $properties | Select-Object $properties
}

Function Get-CSVFile {
  # Creates the CSV File per group with the group members
  param(
    [Parameter(Mandatory = $true)]
    $group,

    [Parameter(Mandatory = $true)]
    $users
  )

  # Create CSV File path with Groupname and datetime
  $CSVFilePath = $CSVPath + "\" + $group + "-" + (Get-Date -Format "yyMMdd-hhmm") + ".csv"
  
  # Export users to CSV File per Group
  $users | Sort-Object Name | Export-CSV -Path $CSVFilePath -NoTypeInformation -Encoding UTF8

  if ((Get-Item $CSVFilePath).Length -gt 0) {
    Write-Host "- Report finished and saved in $CSVFilePath" -ForegroundColor Green
  } else {
    Write-Host "- Failed to create report" -ForegroundColor Red
  }
}

Function Get-GroupMembers {
  # Get the group members from the specified group
  # and export the results to CSV or console
  param(
    [Parameter(Mandatory = $true)]
    $group
  )
  
  Write-Host "- Getting users for $($group.name)" -ForegroundColor Cyan
  $users = Get-Users -dn $group.distinguishedName

  if ($null -eq $users){
    Write-Host "- No users found in $($group.name)" -ForegroundColor Yellow
    return
  }

  If ($CSVpath) {
    Get-CSVFile -group $group.name -users $users
  } else {
    $users | Sort-Object Name | ft
  }
}

Function Get-Groups {
  # Get the groups, either from the parameter,
  # or lookup all the groups in specified OU
  if ($groupName) {
    foreach ($group in $groupName) {
      Write-Host "- Getting group details for $group" -ForegroundColor Cyan
      $ADGroup = Get-ADGroup -Identity $group
    
      if ($null -eq $ADGroup) {
        Write-host "- Group $group not found" -ForegroundColor Red
        continue
      }
      Get-GroupMembers -group $ADGroup
    }
  }
  elseif ($searchBase) {
    # Get the requested users
    foreach ($dn in $searchBase) {
      Write-Host "- Collecting groups in $dn" -ForegroundColor Cyan
      Get-ADGroup -Filter * -SearchBase $dn | ForEach-Object { Get-GroupMembers -group $_ }
    }
  }
  else{
    # Get distinguishedName of the domain
    $dn = Get-ADDomain | Select-Object -ExpandProperty DistinguishedName
    Write-Host "- Collecting all groups in $dn" -ForegroundColor Cyan
    Get-ADGroup -Filter * -SearchBase $dn | ForEach-Object { Get-GroupMembers -group $_ }
  }
}

# Collect the group members
Get-Groups

Examples

To get all enabled user accounts from the two Active Directory groups, you can use the command below. It will create two CSV files in the folder c:\temp once completed.

Get-ADGroupMembers.ps1 -groupName 'SG_M365_PowerBi','SG_M365_E3' -enabled true-CSVpath 'c:\temp'

If you want to get the members from all groups in a specific OU, then you will need to use the searchBase option. For this, you will need to know the distinguished name of the OU. You can find the distinguished name in the Attribute Editor of the OU:

  1. Open the properties of an OU (right-click > properties)
  2. Open the Attribute Editor tab
  3. Copy the distinguishedName value
Get distinguished name ou

You can then run the script as follows:

Get-ADGroupMembers.ps1 -searchBase 'OU=Groups,OU=Amsterdam,OU=Sites,DC=lazyadmin,DC=nl' -CSVpath 'c:\temp'

Wrapping Up

Exporting the members of an Active Directory group can easily be done with the Get-ADGroupMember cmdlet combined with the Export-CSV cmdlet. But when you have a large environment, want to export multiple groups, or want to include more user details, then this script is a good option.

I hope you liked this article and script, if you have any questions or suggestions, just drop a comment below.

Leave a Comment

0 Shares
Tweet
Pin
Share
Share