Compare Group Membership

One of the things that I love to do when I’m writing scripts is write them in such a way that you can run them over and over again without breaking – for instance, if I have a script to add a bunch of users to a group (something I’m doing all the time during migrations), I want to make sure that the script will evaluate the group membership, compare against the list of accounts I have to add, and then only add the missing ones. This really helps to streamline your process, because if you can add that comparison step, the next time your run your script, it’ll pick up where it left off, and only add the users that aren’t already members. If you don’t have something like this in your script, you’ll end up with a screen full of “The recipient is already a member of the group” errors.

Let me show you what I mean, and how I do this:

Start with a regular csv file that has a UserPrincipalName column header.

Next, we’ll prepare a variable, and pull all our user names into it:

$users = Import-Csv .Desktopusers.csv

In this case, I’m going to be adding users to a distribution group called Journaled Mailboxes, so if you are incorporating this into your script, just change the name of the group that we’re pulling into the $distGroup variable to whatever group you need to target. Let’s grab that group and store it as a variable so we can target it later, and then grab the group membership – note that in this case, we only want the Display Name and the Primary SmtpAddress of our users:

$distGroup = Get-DistributionGroup "Journaled Mailboxes"
$distG = Get-DistributionGroupMember $distGroup.Id | Select DisplayName,PrimarySmtpAddress

Now that we have this information, we’re going to do a Compare-Object on them to build a comparison table – kudos to my buddy Ryan for showing me how this was done! 😀

$userCompare = Compare-Object -ReferenceObject $users.UserPrincipalname -DifferenceObject $distG.PrimarySmtpAddress -IncludeEqual

If we replay our $userCompare variable, we can see something interesting:

See the cool thing about Compare-Object is that it uses what it calls “Side Indicators” to tell you whether or not the objects in one list compare to the other. In the screenshot above => indicates that the object exists in the group, but wasn’t found in the list of users I imported. The <= symbol indicates that the users in question are on my list of imported users, but are not members of the group. The last symbol that we don’t see here yet is ==, which indicates that the users are members of both groups.

Now it’s a fairly simple thing to act on this information and give our script some logic:

foreach ($u in $userCompare){
if ($u.SideIndicator -match "=="){
Write-Host "$($u.InputObject) is already a member" -ForegroundColor Green
elseif ($u.SideIndicator -match "=&gt;"){
Write-Host "$($u.InputObject) is already a member" -ForegroundColor Green
else {
Write-Host "$($u.InputObject) is not a member" -ForegroundColor Red
Write-Host "Adding $($u.InputObject) to $($distgroup)"
Add-DistributionGroupMember -Identity $distgroup.Identity -Member $u.InputObject

What we’re doing is running a simple foreach loop, and reporting back the two conditions that will indicate that the user is already a member of the group (“==” and “=>”), and if it finds the last indicator (“<=”) it adds the users as members of the group. Let’s run it now and see what happens:

In this case, we knew from checking the $userCompare variable earlier that onedrive-test was a member of the group already and not on our list, and the script ran through exactly as we wanted it to. Now let’s see what happens if we run it again:

And then:

All we get is a nice report telling us that everyone is already members – and no red errors because the users are already members of the group. Let’s add a couple more users and run it one more time:

And there you have it – a nice solution to the annoying error “The recipient is already a member of the group”, and a great piece of logic that I keep using over and over again when I’m building out scripts.

Feel free to leave a comment below if you have any questions, or to let me know if this helped you out!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.