Forum Discussion

TomWechsler's avatar
Apr 06, 2022

Exchange Online Quick Tip: Export all distribution lists with members to a CSV file!

 

Hi Microsoft 365 and Exchange Online friends,

 

This article is about using PowerShell in Exchange Online to discover all distribution lists, including all members. Then export this information to a CSV file.

 

I used the PowerShell ISE for this configuration. But you are also very welcome to use Visual Studio Code, just as you wish. Please start with the following steps to begin the deployment (the Hashtags are comments):

 

#The first two lines have nothing to do with the configuration, but make some space below in the blue part of the ISE

Set-Location C:\Temp
Clear-Host

 

#We need the module (without the parameter for a specific version)
Install-Module -Name ExchangeOnlineManagement -AllowClobber -Force -Verbose

 

#Let's import the module
Import-Module ExchangeOnlineManagement

 

#Check the version (if you have not selected a version)
Get-InstalledModule -Name ExchangeOnlineManagement

 

#Update if needed
Update-Module -Name ExchangeOnlineManagement -Verbose

 

#Now we connect to Exchange Online
Connect-ExchangeOnline

 

#To list all the distribution groups
Get-DistributionGroup -ResultSize Unlimited

 

#To obtain a list of group members
Get-DistributionGroupMember -Identity "MarketingTeam20220406114100" -ResultSize Unlimited

 

#Get members from a given distribution list and then, export its members to a CSV file
$DLName = "MarketingTeam20220406114100"

 

Get-DistributionGroupMember -Identity $DLName -ResultSize Unlimited |
Select Name, PrimarySMTPAddress, RecipientType |

Export-CSV "C:\Distribution-List-Members.csv" -NoTypeInformation -Encoding UTF8

 

##Lets have a look
Get-Content C:\Distribution-List-Members.csv | Out-GridView

 

#Export all distribution lists with members to a CSV file!
$Result=@()
$groups = Get-DistributionGroup -ResultSize Unlimited
$totalmbx = $groups.Count
$i = 1
$groups | ForEach-Object {
Write-Progress -activity "Processing $_.DisplayName" -status "$i out of $totalmbx completed"
$group = $_
Get-DistributionGroupMember -Identity $group.Name -ResultSize Unlimited | ForEach-Object {
$member = $_
$Result += New-Object PSObject -property @{
GroupName = $group.DisplayName
Member = $member.Name
EmailAddress = $member.PrimarySMTPAddress
RecipientType= $member.RecipientType
}}
$i++
}
$Result | Export-CSV "C:\All-Distribution-Group-Members.csv" -NoTypeInformation -Encoding UTF8

 

#Lets have a look
$Result | Out-GridView

 

I hope this article was useful. Thank you for taking the time to read the article.

 

Best regards, Tom Wechsler

 

P.S. All scripts (#PowerShell, Azure CLI, #Terraform, #ARM) that I use can be found on github! https://github.com/tomwechsler

12 Replies

  • mfkabir's avatar
    mfkabir
    Copper Contributor
    Hello, you have an excellent script to get members of all Distribution Groups. However, i need to get distribution group members from a csv file containing names and primary smtps of about 500 distribution groups. how can i use your script above to use import-csv and get members of these 500 Distribution groups? your help is appreciated.
    • gymiv's avatar
      gymiv
      Copper Contributor

      When I run the script I get the below error. Can you assist.
      $username = "username@domain"
      $password = Get-Content "C:\test\test.txt" | ConvertTo-SecureString
      $cred = New-Object system.management.automation.pscredential -ArgumentList $username, $password

      Connect-ExchangeOnline -Credential $cred
      Connect-MsolService -Credential $cred

      $Company = Get-MsolCompanyInformation | select -exp DisplayName
      $InitialDomain = Get-MsolCompanyInformation | select -exp InitialDomain
      $host.ui.RawUI.WindowTitle = "You are connected to: " + $Company + " (" + $InitialDomain + ") "



      $Result=@()
      $groups = Get-DistributionGroup -resultsize Unlimited | fl PrimarySMTPAddress
      $totalmbx = $groups.Count
      $i = 1
      $groups | ForEach-Object {
      Write-Progress -activity "Processing $_.DisplayName" -status "$i out of $totalmbx completed"
      $group = $_
      $Result += New-Object PSObject -property @{
      GroupName = $group.DisplayName
      Member = $member.Name
      EmailAddress = $member.PrimarySMTPAddress
      RecipientType= $member.RecipientType
      }}
      $i++}
      $Result | Export-CSV "C:\test\All-Distribution-Group-Members.csv" -NoTypeInformation

      Get-DistributionGroupMember : Cannot bind argument to parameter 'Identity' because it is null.
      At line:8 char:39
      + Get-DistributionGroupMember -Identity $group.Name -ResultSize Unlimit ...
      + ~~~~~~~~~~~
      + CategoryInfo : InvalidData: (:) [Get-DistributionGroupMember], ParameterBindingValidationException
      + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Get-DistributionGroupMember

  • chipopks's avatar
    chipopks
    Copper Contributor

    TomWechsler 

    Thanks for taking the time to share your solution, Tom.  I have been researching how to do this for a while and your post is the most straight forward and easy to follow that I found.  It worked great for exporting members of a single distribution list and members of all the lists.  My client is happy which means I am also.  I like Microsoft 365, but it can be really frustrating when something that should be very simple to do using the GUI interface doesn't seem to be possible.  

  • bpsgroupie's avatar
    bpsgroupie
    Copper Contributor

    TomWechsler 

    This is great, thank you - I have tried to amend to include the last logon to the script but to no avail. Any chance you could add result LastLogon column please?

     

    Thanks again for a great file

  • v-mcoore's avatar
    v-mcoore
    Copper Contributor
    how can I locate an Office 365 E5 deployment best practice document
  • ProfRabinow's avatar
    ProfRabinow
    Copper Contributor

    TomWechsler Thanks for the post!  I stumbled on this page when looking for a way to set a value for each DL that I have. (a loop through each DL, to run this command for each DL, without having to type each DL name:

    Get-DistributionGroup "<DistributionGroupName>" -ReportToManagerEnabled $true -ReportToOriginatorEnabled $false 

     

    A few questions if you don't mind!

    1) the script you offer to export all DLs....  That's not listed, ready to go, right?  I need to get it from your github?

    2) Github has always confused me.  I click on your link and see loads of repositories (thanks for sharing).  Trying to find this script... is there a easy way?

    I search in repositories on the word export.  nothing comes up. 

     

    Scrolling in the list, you have several related to m365 - for example, 

    https://github.com/tomwechsler/Microsoft365

     

    How does someone know what each file does?  The readme.md doesn't have info.  I need to get each file, and read the comments?

     

    Thanks!

  • TMotes's avatar
    TMotes
    Copper Contributor

    TomWechsler I've found that using GUID works very well instead of group name for the -identity field. You can run into duplicated group names in some legacy environments, but GUID will always be unique to the group. Overall, a great script that has come in very handy!

  • Scooby340's avatar
    Scooby340
    Copper Contributor

    TomWechsler Thank you for the easy to follow steps!

     

    I have nested groups, what would I need to put in to get the members of those nested groups? e.g. Group A contains Group B which contains Group C, so when I run the script I only get the email address for group B, but I also need the list of users in group B and Group C. Any help appreciated. Thank you.

  • jenn_s_'s avatar
    jenn_s_
    Copper Contributor

    TomWechsler  Thanks so much, this worked like a charm for me. How can I modify it to include Microsoft 365 groups?

Resources