6

Assume I have a distribution group in Exchange which currently exists, and holds about 20 members.

In Powershell 2, I have acquired a list of about seven hundred more individuals who need to be added to the group. The only way I have been able to do this is one user at a time:

Add-DistributionGroupMember -Idneity GROUP-NAME -Member Member1
Add-DistributionGroupMember -Idneity GROUP-NAME -Member Member2
....
Add-DistributionGroupMember -Idneity GROUP-NAME -Member MemberN

Is there a mechanism available that allows me to add all users with just one function call, as represented by the following pseudo-code?

SOME-CMDLET-TO-ADD-LOTS-AT-ONCE -Identity GROUP-NAME -Member COLLECTION-OF-PEOPLE

I'm not looking for loop constructs. I'm looking for a function or cmdlet that can add all members at once, ideally taking only one argument referencing the entire list. I'm scared to think what Powershell would do with 700+ command-line arguments...

(I'm hoping that if this IS possible, that I can pass an array or collection of objects to be added.)

Any suggestions? I don't see a command called 'set-distributiongroupmember', and I also don't see anything promising in 'set-distributiongroup'.

11 Answers 11

11

I'm not sure why you don't want to use a loop construct; that's kinda one of the major features of PS. A simple:

Import-CSV FileName.csv | ForEach {Add-DistributionGroupMember -Identity "GROUP-NAME" -Member $_.Name}

would easily do the trick. Failing that, though, there's no cmdlet to do exactly what you want. You could do a

Remove-DistributionGroup GROUP-NAME; New-DistributionGroup -Name GROUP-NAME -Members memberlist

but that's a little cheesy.

7
  • The reason I don't want to use a loop construct is that I have empirical evidence that suggests performing one call to interact with a distribution group is orders of magnitude faster than making the same call to interact with a distribution group hundreds of times. It's about performance, which a loop construct doesn't give me. It's pretty sad and inconsistent that new-distributiongroup lets you specify a list argument, but add-distributiongroup doesn't.
    – Larold
    Sep 28, 2011 at 20:54
  • What is this evidence? I'd be curious to see if what you did was a true "apples-to-apples" comparison. I'd like to run the test myself.
    – pk.
    Sep 28, 2011 at 21:24
  • Gather a list of 1,000 email addresses. Create mail contacts for them. Then add them to a distribution group one at a time with add-distributiongroupmember. Then, for comparison, make a call to new-distributiongroup with 1,000 of those contacts in the single array argument. Additionally, try calling get-distributiongroupmember one member at a time for a whole group, then try returning everyone at once. In short - every call that connects to AD or Exchange produces significant overhead. That's why I only want one call to add everyone in my array.
    – Larold
    Sep 29, 2011 at 1:42
  • 1
    My results: Add-DistributionGroupMember x 1000 : 2m 13s --- New-DistributionGroup $arrayof1000Contacts : 17s = significant enough difference to care
    – pk.
    Sep 29, 2011 at 14:15
  • @pk - thanks for confirming. That's why I'm dying for functionality to pass an array to add-distributiongroup, just like you can pass to new-distributiongroup. Definitely something MS should consider in future releases.
    – Larold
    Sep 29, 2011 at 14:43
4

I know this is an old post, but it's still the #1 result on Google when trying to find how to add multiple users to a DL so I figured I'd post my solution.

The previous solutions will work fine for a small list of users, but as the original poster stated there are performance and scaling issues with calling Add-DistributionGroupMember for every member when dealing with large membership changes, and this is compounded when dealing with O365.

To solve these issues you can use Update-DistributionGroupMember to replace the entire membership of a DL instead of adding them one by one.

e.g. for the original request you would do this:

Update-DistributionGroupMember -Identity GroupName -Members user1@domain,user2@domain,usern@domain

or

Update-DistributionGroupMember -Identity GroupName -Members $ArrayOfMemberEmailAddresses

This does replace the membership of the DL, so if you wanted to maintain the existing membership you would need to retrieve it first using Get-DistributionGroupMember then create an array of the existing members and new ones and give that to Update-DistributionGroupMember like the following:

$NewMembers = Get-Content <path to member list text file>
$CurrentMembers = (Get-DistributionGroupMember -Identity GroupName).PrimarySmtpAddress | where {$_ -ne ""}
$NewMemberList = $CurrentMembers + $NewMembers
Update-DistributionGroupMember -Identity GroupName -Members $NewMemberList -Confirm:$false

Lastly, if you're trying to update the membership on a ton of DLs in O365 like I needed to, then you can add the -AsJob switch to the Update-DistributionGroupMember command in your loop so that it runs all the updates in parallel rather than waiting for each membership update to finish before moving on. This will vastly speed up your script, but make sure you do some reading on PowerShell remoting and using Jobs first if you aren't familiar with them yet as there is some additional work you'll need to do afterwards to get the results, check for errors etc.

Doing it this way instead of using Add-DistributionGroupMemberreduced the number of commands sent to O365 for my DL migration from somewhere around 150K to about 2.5K and reduced my script runtime from multiple days to an evening for migrating the membership of 1200 DLs.

4
  • Per my understanding of how Stack works, it is preferred to keep a question current instead of adding new instance of a question.
    – Jeter-work
    Mar 18, 2020 at 15:04
  • Good to know, I've had a few other forums etc. where I've gotten flak for "Resurrecting dead threads" so figured I'd put the disclaimer up front. Mar 18, 2020 at 17:52
  • OP here: Thanks for following up with an effective methodology, even though I haven't touched this project in almost 9 years. :) I'm a lifelong Unix / Linux guy who has historically been frustrated with MS products and infrastructure. It's nice to know I wasn't crazy and that this was indeed a challenging task for the community at large. Cheers!
    – Larold
    Mar 19, 2020 at 1:27
  • Also works against a lot of people, I've posted questions that I couldn't find the answer to, but it may be loosely related to another question someone asked 10 years ago and my question gets closed, despite being a very different issue.
    – HippoDuck
    Mar 8, 2021 at 14:19
2

Successfully populated a Distribution Group by creating a text file, populating with member account aliases, then executing the command:

% Get-Content <path\filename.txt> | Add-DistributionGroupMember "<Display Name of Distribution Group>"

See these URLs for further details:

2

Not sure why the teams at Microsoft made this so complicated. Sometimes you just have to think simple.

"user1","user2","user3" | Add-DistributionGroupMember -Identity "SomeMailbox"
1

Try this, it seems to work for me:

Get-Content | Add-DistributionGroupMember

Text file just contains the aliases of the users that you want to add.

1
  • will fail on user who is already a member
    – filimonic
    Jan 31, 2015 at 4:20
0

It looks like the Quest Active Directory PowerShell Cmdlets can add multiple users to a group at one time per this wiki page. In my brief testing, I was able to use the Add-QADGroupMember cmdlet to add a small array of users to a test group in Active Directory.

0

It might be helpful too to add AD with this:

import-module ActiveDirectory

Then just use:

Add-AdgroupMember MyList -member user.alias,user2.alias,user3.alias,...

For this you do need RSAT installed (MS product, and free) or it won't work.

1
  • 1
    How does this solve the problem of the manual repetition the OP is interested in avoiding?
    – squillman
    Nov 19, 2014 at 17:29
0

If performance is a concern Add-ADGroupMember is by far the fastest, and as mentioned can take an array as input to the -Member parameter.

1
  • Add-ADGroupMember will break on adding a member already in group
    – filimonic
    Jan 31, 2015 at 4:45
0

Something like that, not sure if this is well-written or working - just an idea.

Function Add-DistributionGroupMembers_Safe {
Param (
    [Parameter(Mandatory=$true)]
    [String]$Identity,
    [Parameter(Mandatory=$true)]
    [String[]]$Member
)
    $local:groupADSI = [ADSI]"LDAP://${$(Get-DistributionGroup -Identity $Identity).DistinguishedName}"
    $local:DGUsers = @( @( Get-DistributionGroupMember -Identity $Identity ).Name )
    $local:UsersToAdd = @( $Member | Where-Object { $local:DGUsers -notcontains $_ } | ForEach-Object { return (Get-ADUser -Name $_}).DistinguishedName )
    ForEach ($user in $local:UsersToAdd) {
        try {
            $local:GroupADSI.Properties["member"].Add($user) | Out-Null
        } catch {
            #Error processing, text in $_.Exception.Message
        }
    }
    $group.CommitChanges()
}
0

For adding bulk users from text file use the below script, it is very easy to use and this guy has written pretty neat

https://gallery.technet.microsoft.com/Add-Bulk-Users-to-6f3014b2

1
  • 1
    you might want to add the relevant part of the script, show perhaps which features it uses so one can create an own script. given that the link might not work some time in the future your answer will not help if the link breaks. Mar 12, 2019 at 16:55
0

Get-EmailString -InputString "user1", "user2", "user3", "user4" | Add-DistributionGroupMember -Identity "DLNameGoesHere"

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .