Using Powershell to list group membership from Active Directory (AD)

The following post by Terri, a Support Specialist with OrcsWeb managed Windows hosting, should prove to be very helpful for any administrators or developers looking to list group memberships from Active Directory. Below is just one example of the many tasks Terri performs for both Windows Cloud Hosting and Dedicated Windows hosting clients.


How many times have you needed to list group membership for multiple groups in AD? This can be a painstaking process if performed manually. I was recently asked to perform an audit of all of a client’s users and groups. I was also asked for a listing of what access each had at a file level on the client’s hosted servers.

The first step, of course, involved gathering the AD data for the client. You can export data from AD to a CSV file which makes gathering the user and group names quite easy. The painstaking part is getting the group membership information. Here is a nifty little script that I put together to grab the group members and write them out to a text file on the local system. This powershell script requires the ActiveDirectory module and a csv file which lists the groups for which you want to gather the members.

<#
This script can be used to list group membership from AD
It utilizes the ActiveDirectory module to interface with AD
by Terri Donahue
#>

Import-Module ActiveDirectory
cd AD:
$MemberList = New-Item -Type file -Force “c:\scripts\GroupMembers.csv”
Import-Csv “C:\Scripts\Groups.csv” | ForEach-Object {
$GName = $_.GroupName
$group = Get-ADGroup $GName
$group.Name | Out-File $MemberList -Encoding ASCII -Append
foreach ($member in Get-ADGroupMember $group)
{
$member.Name | Out-File $MemberList -Encoding ASCII -Append
      }
$nl = [Environment]::NewLine | Out-File $MemberList -Encoding ASCII -Append
}

The formatting of the csv file is very important. There needs to be a column header and then the group names are the fully qualified LDAP locations. Here is what my test group file contained:

GroupName
“CN=Test1,CN=Users,DC=td,DC=com”
“CN=Test2,CN=Users,DC=td,DC=com”

You will notice that the column header “GroupName” is what is referenced in the script for the $GName variable. That value can be anything but has to match.

Once this script has completed, you will have a text file which lists each of the groups followed by the members of the group.

Hopefully you found this as helpful as I did. If you would also like additional information about Icacls and how it can be used to review, save, and restore NTFS permissions, please check out my other blog post, Viewing, Saving and Restoring NFTS Permissions.

If you are interesting in creating multiple AD users programmatically, take a look at another post I wrote that includes the script to do just that.

You can follow all of Terri’s helpful blog posts HERE.

Be Sociable, Share!

    21 Comments.

    1. Hello Terri,

      We have been looking for a way to enumerate nested group memberships, and we know how difficult it is, as we have tried it in our environment.

      One of the challenges we have is that we have some circular loops in our group memberships, so I wanted to know if your script can detect and avoid circular loops when enumerating group memberships.

      Here is what I am talking about – Why is it so hard to enumerate nested group memberships in Active Directory?.

      This thing is just a real mess and pain for us. We are not sure how we ended up with circular loops, but its causing quite a headache.

      I would love to know if your script can deal with this? If so, I will try it in a jiffy!

      Thank you for your reply.

    2. Terri Donahue

      Just to make sure I understand your question. Let’s say you have group1, group2, and group3. group3 is a member of group1. If you list group1 and group3 in the glist.csv file, you will get the membership of group1 including the group3 name but members. Then you will get the members of group3 listed separately. The script is able to process this without any errors since it is not recursively traversing the groups but simply listing the members.

    3. Hi Terry

      Where do I substitute the name of our AD Group in your script?

      I have very little (none infact) knowledge of powershell.

      Thanks
      David

      • Hi David,

        Create the following file: C:\Scripts\Groups.csv. This is where the groups are listed. The contents of the file will look like this:

        GroupName
        “CN=Test1,CN=Users,DC=td,DC=com”
        “CN=Test2,CN=Users,DC=td,DC=com”

        The first line has to be GroupName. Update the canonical names listed below GroupName with the name/location of your AD groups.

    4. Thanks Terri I feel as though I am close to doing this with your kind help. So just so I understand I need to create the csv file in the directory specified. I DONT need to alter it? I dont know what CN and DC mean so am not sure about altering the file if I need to. My domain is xswhc and the AD group I want to list users is called ggpctrep2. Do I need to substitute these into your very clever script. Is the script designed to do ALL global groups? I am sorry I just need more help.

      Many thanks
      David

      • Hi David

        You do have to update the file with the relevant information related to your AD directory structure. You will need to specify the canonical layout of each group that you want to list membership for. In my example, I was listing the membership for specific groups named Test1 and Test2.

        • Its all a bit of a mess Terri, I put your script in a new csv file and saved the csv file above as instructed. Went to a powershell prompt and ran it with this disasterous error message. I changed the execution policy following reading
          Like you advised all I changed in the csv was the AD groups that I want to enumerate. Pleaes help, thanks

          Execution Policy Change
          The execution policy helps protect you from scripts that you
          you to the security risks described in the about_Execution_Po
          policy?
          [Y] Yes [N] No [S] Suspend [?] Help (default is “Y”): y
          PS C:\Windows\system32> cd\
          PS C:\> c:\scripts\powerfile.ps1
          Import-Module : The specified module ‘ActiveDirectory’ was no
          ule directory.
          At C:\scripts\powerfile.ps1:7 char:14
          + Import-Module <<<< ActiveDirectory
          + CategoryInfo : ResourceUnavailable: (ActiveDir
          + FullyQualifiedErrorId : Modules_ModuleNotFound,Microsof

          Set-Location : Cannot find drive. A drive with the name 'AD'
          At C:\scripts\powerfile.ps1:8 char:3
          + cd <<<< AD:
          + CategoryInfo : ObjectNotFound: (AD:String) [Se
          + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerSh

          The term 'Get-ADGroup' is not recognized as the name of a cmd
          spelling of the name, or if a path was included, verify that
          At C:\scripts\powerfile.ps1:12 char:21
          + $group = Get-ADGroup <<<< $GName
          + CategoryInfo : ObjectNotFound: (Get-ADGroup:St
          + FullyQualifiedErrorId : CommandNotFoundException

          The term 'Get-ADGroupMember' is not recognized as the name of
          ck the spelling of the name, or if a path was included, verif
          At C:\scripts\powerfile.ps1:14 char:38
          + foreach ($member in Get-ADGroupMember <<<< $group)
          + CategoryInfo : ObjectNotFound: (Get-ADGroupMem
          + FullyQualifiedErrorId : CommandNotFoundException

          The term 'Get-ADGroup' is not recognized as the name of a cmd
          spelling of the name, or if a path was included, verify that
          At C:\scripts\powerfile.ps1:12 char:21
          + $group = Get-ADGroup <<<< $GName
          + CategoryInfo : ObjectNotFound: (Get-ADGroup:St
          + FullyQualifiedErrorId : CommandNotFoundException

    5. (Get-Group -Identity groupname).members | get-user | sort displayname | ft name, displayname -au

    6. I’m not sure why, but maybe I’m not submitting this right. I copied the text above to notepad, changed the appropriate file names, etc, but when I copy and paste it into powershell, I just get the >> at the end and it doesn’t “do” anything. What am I doing wrong?

      • Copy the script and paste it into Notepad or another text editor. Then save the file as filename.ps1. Within powershell, run filename.ps1.

        • Thank you so much! I also realized that I referred to the same file in both lines that reference files, thus stepping on itself :S… Looks like it is working now. Thanks again for a great script!

    7. Great script, thx!
      I was wondering if it is possible to list the groupmembers recursively?

    8. Great script – is there a way to get more information listed for each user?

    9. Hi lads,

      i can’t get this script to giove me any data, have tryed to change everything that would make sence, how ever. it is making a file, without any info. could you help me where my error is?
      ——————————————–
      Import-Module ActiveDirectory
      cd AD:
      $MemberList = New-Item -Type file -Force “c:\scripts\GroupMembers111.csv”
      Import-Csv “C:\Scripts\Groups.csv” | ForEach-Object {
      $GName = $._C_SET_ALLOW_LOCAL_ADMINS
      $group = Get-ADGroup C_SET_ALLOW_LOCAL_ADMINS
      $group.Name | Out-File $MemberList -Encoding ASCII -Append
      foreach ($member in Get-ADGroupMember $CN=C_SET_ALLOW_LOCAL_ADMINS,OU=Top-Settings,DC=Bane,DC=dk)
      {
      $member.Name | Out-File $MemberList -Encoding ASCII -Append
      }
      $nl = [Environment]::NewLine | Out-File $MemberList -Encoding ASCII -Append
      }
      ————————————————–
      the full location to this group is: CN=C_SET_ALLOW_LOCAL_ADMINS,OU=Top-Settings,DC=Bane,DC=dk

    10. Exactly what I needed. Worked great. Thanks