Large distribution groups can lead to some unfortunate incidents in an Exchange organization, such as the one that occurred at Reuters recently when a person was able to send to 33,000 recipients, causing a server-crushing increase in email traffic as hundreds of those recipients proceeded to “reply all”.
One of the precautionary measures you can take is restricting who can send to your largest distribution groups. Of course this means you must first identify those groups, which is quite simple to do with PowerShell.
The Exchange management shell includes a Get-DistributionGroupMember cmdlet that can output the members of a distribution group. This cmdlet has one flaw in that it does not perform a recursive search. For example, this “All Staff” distribution group has two smaller groups nested in it as members, which then contain the several hundred individual recipients. If we use Get-DistributionGroupMember it tells us that there are two members, which is true in one sense, but quite useless for our objective here.
[PS] C:Scripts>(Get-DistributionGroupMember "All Staff").Count 2
Sure, we could build a script with a recursive function that expands the membership of any groups contained within other groups, and that would do the job. But that’s a bunch of code that isn’t necessary, because fortunately an Active Directory PowerShell cmdlet comes to the rescue. Get-ADGroupMember has a -Recursive switch to handle this for us.
[PS] C:Scripts>(Get-ADGroupMember -Recursive "All Staff").Count 389
So let’s say that we want to produce a report of all distribution groups that contains their names, member counts, and managers as well (in case we need to discuss any restrictions on the group with the owner/manager). I’ve written a simple PowerShell script to do just that.
Download Get-DGMemberCounts.ps1 from Github
Here’s an example of the script running.
[PS] C:Scripts>.Get-DGMemberCounts.ps1 Payroll Team has 3 members Public Folder Owners has 2 members Head Office Staff has 386 members All Staff has 389 members Regional Office Staff has 4 members All Office Meeting Rooms has 3 members Deny Outgoing External Email has 1 members ZTestExternal2 has 1 members Security Team has 0 members Social Club has 3 members App_Tier2_ABCDEF has 1 members DL_Alannah.Shaw has 2 members DL_Mike.Ryan has 2 members DL_ex2010test has 1 members
And the resulting CSV file.
The Real Person!
Author SD acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
Hi
Could you please provide an script to extract/report with all distribution groups (static and dynamic) with the following columns.
Displayname, Members Count, AcceptMessagesOnlyFrom, ModerationEnabled, ModeratedBy
The Real Person!
Author Tony Redmond acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
I certainly could provide such a script, but you’ll find that it will take you a little time to write the script and at the end of the experience, you’ll feel much better that you did it rather than me.
The Real Person!
Author Tony Redmond acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
And a simple search will find lots of examples, like https://office365itpros.com/2022/12/06/distribution-list-membership-sdk/
Pingback: Getting Exchange Online Distribution List Membership Counts with PowerShell
Hi Paul,
Thanks for the script.
when i am using below lines, its not counting the members in child groups. can you please help on it.
#Get distribution groups
$distgroups = @(Get-ADObject -LDAPFilter β(&(objectclass=group)(mail=*))β -Properties name, distinguishedName, managedby, mail)
#Process each distribution group
foreach ($dg in $distgroups)
{
$count = @(Get-ADGroup $dg.distinguishedname -Properties member |Select-Object -ExpandProperty member|Get-ADObject -Properties Samaccountname,DistinguishedName |select Samaccountname,DistinguishedName,ObjectClass).Count
For O365 users just use this :
(Get-DistributionGroupMember -Identity “Name of your group”).count
The Real Person!
Author Tony Redmond acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
That’s the count of objects in the DL. It doesn’t expand nested DLs into their members.
Hi , Is there a way to use the script if i dont have exchange on Prem? We use o #65 Exchange and we synch AD to Azure .
Hi,
Great script. I to had to import-module activedirectory in PS to retrieve member count. Also as per the earlier post I had to remove .name from this line:
$reportObj | Add-Member NoteProperty -Name βManagerβ -Value $dg.managedby.Name
for the Manager field to populate any data.
However the data which populates the Manager column is as follows – am I missing something
“Microsoft.Exchange.Data.Directory.ADMultiValuedProperty`1[Microsoft.Exchange.Data.Directory.ADObjectId]”
Many Thanks
Hi Everyone,
The script is really good, while i tweaked the script at few places. The ManagedBy property is not getting into csv. Please let me know if any PS module needs to be loaded or please share the script those who have already tried and working.
Any updates to this script?
Paul,
Any chance you got this to work with 365? This script is extremely helpful.
Thanks
-Samad
I got it working by commenting out if/else for the RemoteExchange, and loaded the $LiveCred and Import-PSSession however, i got an error for the Set-ADServerSettings, and it says all my groups have 0 member count.
GROUP has 0 members
Get-ADGroupMember : Cannot find an object with identity:
Not sure but think somehow its not connecting to AD properly even tho it spits out the information for group names, and DN names. Just always showing 0 counts. Im on O365 and not exchange physical tho
How do I get this working for O365 ?
Hey Paul,
How do i achieve this using Exchange online? I need to export the DL members/Nested or recursive Members and Null Members
This script retrieves Group members count from GROUPMETRICS data using EWS query which is maintained by Exchange itself for MailTips purpose.
This is useful in a situation where a group has child groups or nested groups and fast in getting data.
https://gallery.technet.microsoft.com/Retrieve-Distribution-63ac2549
Hi,
I have a distribution group in Exchange 2013 on premise called grupoempresas@meudominio.com.br, and this group has the amount of more than 850 members. And to enter the group name created in the recipient field (Outlook / Webmail) the error appears below:
You are not allowed to send: grupoempresas@meudominio.com.br
gruposempresas @ mydomain contains about 901 recipients.
The following documentation (https://technet.microsoft.com/pt-br/library/exchange-online-limits.aspx#DistributionGroupLimits), reports that the limit is 100,000 and sending up to 5,000.
Any tips to release shipments for this group?
Sorry translation, do not understand much English.
Grateful!
Thiago Rocha!
How can I change the scope to be distribution lists which start with a specific word?
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
Edit the script so this line only returns the groups you’re interested in.
#Get distribution groups
$distgroups = @(Get-DistributionGroup -ResultSize Unlimited)
Hi
Could you please help me to get list of authored (authOrig) users to send the mail to DLs.
DL name Members authored user list
The script works great with 2 exceptions.
I had to remove .name from this line:
$reportObj | Add-Member NoteProperty -Name “Manager” -Value $dg.managedby.Name
I have some groups that are over the 5,000 limit placed on what I believe is ADWS. I get this error:
Get-ADGroupMember : The size limit for this request was exceeded
FullyQualifiedErrorId : The size limit for this request was exceeded,Microsoft.ActiveDirectory.Commands.GetADGroupMember
Yes the program canβt count over 5000.
Why?
The Get-ADGroupMember commandlet has a restriction on the domain controller limiting it to 5000 results by default. The restriction is on the under MaxGroupOrMemberEntries attribute in the Microsoft.ActiveDirectory.WebServices.exe.config file, under C:\WindowsADWS directory.
any workaround for this restriction of 5000?
Thought This might help people who has more than 5000 member’s groups
#Get distribution groups
$distgroups = @(Get-ADObject -LDAPFilter “(&(objectclass=group)(mail=*))” -Properties name, distinguishedName, managedby, mail)
#Process each distribution group
foreach ($dg in $distgroups)
{
$count = @(Get-ADGroup $dg.distinguishedname -Properties member |Select-Object -ExpandProperty member|Get-ADObject -Properties Samaccountname,DistinguishedName |select Samaccountname,DistinguishedName,ObjectClass).Count
I am running the script on Exchange 2010 Server and I get all zero for all groups. What should I do?
If you are getting Zero for all groups you don’t have the AD snapin on powershell – add that and run and you are GTG
Not sure if thats the case. I am using ‘Import-Module ActiveDirectory’, and I still get 0 counts. I think it has do with Set-ADServerSettings command as I get an error there but. but I also had to remove the RemoteExchange part
Hi,
Downloaded and run the script but it shows zero 0 for all group, do I need to change something in the script?
Hi Paul,
Thanks for this great script, I used it and managed to get full list of all our distribution groups member count.
however,
the Dynamic distribution groups were not included on the report.
what should I add in order to see the dynamic distribution groups on the report?
Many Thanks.
I can filter by OU the search? example: $distgroups = @(Get-DistributionGroup -ResultSize Unlimited | where {$_.identity -like “Ou../pais/groups/*”})
Thank You.
It doesn’t work without Active DIrectory module.
Paul in my environment we have 3 child domains containing the users, while the Exchange servers are members of only one of the child domains. When I run the script in the domain containing the servers it does not correctly count the members if they are in one of the other child domains.
For example group “All Staff” has members from all 3 child domains but the script only counts the members of the domain the script was run from leaving out the members of the other 2 domains.
Any suggestions to span multiple domains? Other scripts I have written required 3 domaincontroller variables but not sure how I would add that in this script.
awesome
Thanks
Hi Paul
I was going to use this to clean up empty distributiongroups. But then I saw some groups was displayed as “0” members from your script. But I knew there were members in them .
Example: http://i.imgur.com/yYE0E4D.png
This is mail contacts for external users/customers.
I guess I’m using my old script for this π
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
So the group contains only mail-enabled contacts? I will have to test that out, I have no groups like that in my lab right now π
I have noticed the same – the Get-ADGroupMember cmdlet will return neither Mail Contacts nor PublicFolders that might be part of a distribution group.
I don’t know if there’s any way around that, unfortunately, I came here while looking for a solution myself.
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
The solution is to write a recursive function, which I was hoping to avoid in this case, but with this revelation that some objects aren’t returned by the AD cmdlet I’ll dig up one of my old samples and update this post and script soon π
I know this is an old thread, but did you find your script that would detect mail contacts in distribution groups and count them?
Hi Paul
great script. when I am trying to run it I am getting this error thou.
The ‘<' operator is reserved for future use.
At C:usersagentnavzDesktopGet-DGMemberCounts.ps1:50 char:11
+ <!– < <<< –>
+ CategoryInfo : ParserError: (<:OperatorToken) [], ParseException
+ FullyQualifiedErrorId : RedirectionNotSupported
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
What version of Powershell? And have you modified the script at all?
PSVersion 2.0
and nope…I downloaded the script as is.
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
If you open the script in the PowerShell ISE my guess is you’ll see a bunch of HTML code that doesn’t belong there. Click on the script instead so you can see the actual PowerShell code.
Awesome post as usual. Any thoughts on a report for when an Exchange Distribution Group was last used? Guessing that eventually Microsoft will add this as a tracked attribute as the only way that I can think of is tracking EXAND events in message tracking.
Any thoughts?
The Real Person!
Author Paul Cunningham acts as a real person and passed all tests against spambots. Anti-Spam by CleanTalk.
Message tracking is the only way I know of to get this info right now.