Get-DistributionGroupMember Recursively


I had a need to get distribution group members for a specific group. Most people seem to install the free “ActiveRoles Management Shell for Active Directory” from Quest Software when they are facing a task such as this.

With the Quest “ActiveRoles Management Shell”, you can do this like “Get-QadGroupMember <group name>–Indirect”

I’m kind of contrary, and so I wanted to do the same thing with the Exchange Management Shell that came with our Exchange 2007 installation. So, I created the script shown here. Save it as get-exgrouprecurse.ps1.

Run it as:

get-exgrouprecurse -group <group name>

or get-exgrouprecurse <group name>

  1. #####################################
  2. #                                   #
  3. # Script to retreive group members  #  
  4. #                                   #
  5. #    Karl Mitschke March 7 2008     #
  6. #                                   #
  7. #####################################
  8.  
  9. ######################################
  10. #  heavily modified from recipe 7.3  #
  11. #   in 'Active Directory Cookbook'   #
  12. #          by Robbie Allen           #
  13. ######################################
  14.  
  15. #requires -pssnapin Microsoft.Exchange.Management.PowerShell.Admin
  16. param($group)
  17. $UnknownGroup = @{}
  18. function DisplayMembers($group)
  19. {
  20.     $SubGroup = @{}
  21.     $AllMembers = @()
  22.     if(!$group)
  23.     {
  24.         $group = Read-Host "Enter the groups display name"
  25.     }
  26.     if ($group.Contains("'"))
  27.     {
  28.         $group = $group.Replace("'",'"')
  29.     }
  30.     if ($group -eq "/?")
  31.     {
  32.         Write-Host "Usage:"
  33.         Write-Host ""
  34.         Write-Host "get-exgrouprecurse -group <group name>"
  35.         Write-Host ""
  36.         Write-Host "or get-exgrouprecurse <group name>"
  37.         Write-Host "Returns an object containing the group member, and the group name."
  38.         break
  39.     }
  40.     
  41.     $validate = Get-Group $group
  42.     if ($validate.RecipientTypeDetails.ToString() -match "mail")
  43.     {
  44.         $searchGroup = Get-DistributionGroupMember $group
  45.         if ($searchGroup)
  46.         {    
  47.             foreach ($member in $searchGroup)
  48.             {
  49.                 $membertype = $member.RecipientTypeDetails
  50.                 if($membertype -match "Group")
  51.                 {
  52.                     $samname = $member.SamAccountName.ToString()
  53.                     if ($SubGroup.ContainsKey($samname) -eq $true)
  54.                     {
  55.                         Write-Output "^ already seen group member (stopping to avoid loop)"
  56.                     }
  57.                      else
  58.                     {
  59.                         $SubGroup.Add($samname,$member.DisplayName.ToString())
  60.                     }
  61.                 }    
  62.                 else
  63.                 {
  64.                     if($member.PrimarySmtpAddress -and $member.RecipientTypeDetails -notcontains "group")
  65.                     {
  66.                         $obj = new-object psObject
  67.                         $obj | Add-Member -membertype noteproperty -Name GroupMember -Value $member.name
  68.                         $obj | Add-Member -MemberType noteproperty -Name GroupName -Value $group
  69.                         $AllMembers += $obj
  70.                     }                    
  71.                 }
  72.             }
  73.         }
  74.         else
  75.         {
  76.             $UnknownGroup.add($group,1)
  77.         }
  78.         if($SubGroup.Values.Count -gt 0)
  79.         {
  80.             foreach ($subGroup in $SubGroup.values)
  81.             {
  82.                 DisplayMembers $subGroup
  83.             }
  84.         }
  85.         if ($UnknownGroup.Keys.Count -gt 0)
  86.         {
  87.             foreach ($LostGroup in $UnknownGroup.keys)
  88.             {
  89.                 $obj = new-object psObject
  90.                 $obj | Add-Member -membertype noteproperty -name GroupMember -Value "Cannot enumerate group"
  91.                 $obj | Add-Member -MemberType noteproperty -Name GroupName -Value $LostGroup
  92.                 $AllMembers += $obj
  93.             }
  94.             $UnknownGroup.Clear()
  95.         }    
  96.     }    
  97.     else
  98.     {
  99.         Write-Output "$group does not appear to be mail enabled."
  100.     }
  101.     Write-Output $AllMembers
  102. }
  103. DisplayMembers $group

  1. #1 by Lars on August 4, 2010 - 13:59

    Hi! Excellent script thanks!!

    Question, how do I make the script pull out the email address and displayname of the users in the group

    is that possible?

    thanks Lars

    • #2 by karlmitschke on August 4, 2010 - 17:32

      Lars;
      I’m a little confused – the $member.name IS the dis[play name for me.

      Regardless, adding the following to the two sections where we build the $obj will work:

      $obj | Add-Member -MemberType noteproperty -Name DisplayName -Value $member.DisplayName
      $obj | Add-Member -MemberType noteproperty -Name EmailAddress -Value $member.PrimarySMTPAddress

      Karl

  2. #3 by david on September 28, 2010 - 17:38

    Thanks for the script. While I was trying to accomplish something slightly different, your code helped!

  3. #5 by albertwt on February 24, 2011 - 17:27

    yes Karl is great 🙂

  4. #6 by Raj on February 28, 2011 - 11:33

    Hey Karl,

    I want to attach the photos of the users on Outlook 2007. I have named the photos to match with the display names of the users. Also I have created a .CSV file with all the users from the active directory. The photos are located in a folder on the same shared drive. I know that I need to use Get-DistributionGroupMember with foreach loop. But I really dont know how to go about it. Please can you help me with this.

    Thanks in advance.

    • #7 by Karl Mitschke on August 29, 2011 - 09:25

      Raj;

      That’s outside ths scope of this article.
      You could email me and I will look into this.

      Karl

  5. #8 by vikram khanna on October 25, 2011 - 05:41

    Hi Karl – thanks a lot for this script – how can I export the output to an excel file. Please let me know.

    Thanks.
    Vikram

    • #9 by Karl Mitschke on October 25, 2011 - 08:17

      get-exgrouprecurse.ps1 -Group <groupname. | Export-Csv -Path C:\scripts\.csv -NoTypeInformation

  6. #10 by keltz on December 14, 2011 - 02:35

    hi karl,

    how do i fine tune your script to export all the members of all the distribution group in to a csv file for easy reading.

    • #11 by Karl Mitschke on March 20, 2012 - 10:06

      The following should work:

      .\get-exgrouprecurse.ps1 -Group <groupname. | Export-Csv -Path C:\scripts\.csv -NoTypeInformation

  7. #12 by thomesp on November 28, 2012 - 08:24

    script works great. Thanks! One Question, can we show the displayname for memebers of groups?

    • #13 by Karl Mitschke on November 28, 2012 - 09:43

      You should be able to modify line 67 as
      $obj | Add-Member -membertype noteproperty -Name GroupMember -Value $member.DisplayName

      • #14 by thomesp on November 28, 2012 - 10:18

        Thanks very much!

  8. #15 by tim on July 30, 2013 - 15:13

    I am using Exchange 2010 without any 3rd party addins (like Quest). I can’t seem to find how to get this command in 2010:
    get-exgrouprecurse

    is the name of your script ‘get-exgrouprecurse’

  1. Get-DistributionGroupMember Recursively – List of Members Distribution Group » Hakan UZUNER » Cozumpark.Com
  2. Get-DistributionGroupMember Recursively – List of Members Distribution Group
  3. Get Recursive Group Membership of Distribution Group (PowerShell) « christopher law DOT com
  4. Get-DistributionGroupMember Recursively – List of Members Distribution Group | Microsoft Exchange Server Blog
  5. Troubleshooting Distribution Group Member Lists | Email management, storage and security for business email admins

Leave a reply to Karl Mitschke Cancel reply