LiveZilla Live Chat Software

0429 091 360

Update Distribution Group ManagedBy – Exchange 2013

Exchange 2013 Distribution Groups

We are doing an Exchange 2007 to 2013 upgrade at the moment at work in preparation of moving to Exchange Online as part of our Office 365 initiative.

One thing that we ran across is how from Exchange 2010 onward things had changed in how users are allowed to manage Distribution Group membership.


In Exchange 2007 the only way to allow a user to modify a Distribution Group was to assign them in the ManagedBy AD attribute using Active Directory Users and Computers (ADUC). If you needed to allow a group of people this access you needed to create a group and assign the group to the attribute. This was because the attribute was a single value one. However as part of the Exchange schema upgrade from Exchange 2010 SP2+ this was managed with Role Based Access Control (RBAC) groups within Exchange itself and the ManagedBy attribute became a multi value attribute. Because of this the use of Groups to manage Distribution Groups was no longer supported (due to the possibility of creating a looped scenario)


The solution was to get all the members of a group that was assigned ManagedBy access and explicitly add them to then Owners section in Exchange. In effect we were populating the ManagedBy attribute with users rather than the groups.

However for this to work properly we needed to make sure the original group was removed and that if there was nested groups in use that all members of the nested groups were also included.

Therefore I wrote this script. It does the following

  • Takes an input in the form of a complete name (for a single group update) or part of the name (for doing a bulk of groups with the same characters in the name).
  • It then queries the groups ManagedBy attribute and places the value(s) into an array.
  • This array is then passed through a loop. Each of the values is assessed to determine whether it has an ObjectClass of “Group”. If it does it then proceeds to evaluate the group. If not then it is a user and the distinguished name of that user is placed into another array to be used latter.
  • As it checks the group membership it adds the distinguished name of each user in the group into a group array. However it also checks to see if the user has been defined explicitly in the ManagedBy attribute as well. If so it skips that user (to avoid duplication’s).
  • Because a user might be a member of multiple groups and because we are re-cursing through nested groups we then pipe the contents of the Group array into a Final List array only selecting unique values (also to remove duplicates).
  • The script will then replace the current values with the contents of the final list array.
  • This however removes all of the users that were already defined explicitly. This is where the array defined at the beginning comes into play. We loop through that array and use the Set-DistributionGroup -ManagedBy @{Add=$Variable} to add the remaining users.

Here is the code

Break down of script

So let’s look at how this works.

We begin by loading the AD Module and the Exchange PowerShell Snapin’s. I like to make the screen look a bit different so that users know they are in a special session so I change the default colours. Personal preference only.

We then prompt the user for the string of the name of the group they want to run the script against. This can be the entire display name if you wish to run it against a single Distribution Group (e.g. Dist Group 1) or you can type part of the name to capture all groups starting with that name (e.g. assuming you have 4 Distribution Groups named Dist Group 1 through 4 typing Dist Group will run the script against all of these groups).

These are captured by the $DLExpr and $DLList variables. We now use the Get-DistributionGroup ResultSize unlimited Anr $DLExpr command to get either a list of Distribution Groups or a single one depending on the input.

We then need to also initialise two empty arrays using the .net function System.Collections.ArrayList for both $NewOwnersList and $ExistingUser. These will be used a little later to store information.

Now we begin with our first loop.

Nothing to hard here. We grab the value that was assigned to the $DLList variable and pass it through a For Loop to capture some important information needed later. N.B. Through each iteration of the loop we set the values to Null to avoid errors.

We collect the Name and the ManagedBy attributes for each of the Distribution Groups. Now the second loop begins

This part of the loop is designed to identify what ObjectClass has been assigned ManagedBy rights. We have a mix of users as well as groups that we needed to tidy up as we went (i.e. replace the groups with users as per best practise).

So this loop looks at the $OwnersList array and does two main things

  1. It gets the Distinguished Name of the object
  2. Runs a Get-ADObject against it and assigns the result to $OwnerObjInfo

Now that we have the AD Object information we can query the ObjectClass Attribute. If the value is “Group” we run through the next part of our script. If it is anything other than “Group” it will go to the else statement discussed a bit further down.

Lets look at what happens in the first part of the If Statement.

The first thing that happens immediately after we have identified that we are dealing with a group is that we create an array called $UserList by using the Get-ADGroupMember commandlet -recursive. I used the recursive switch because we have some nested groups and I wanted to make sure that everyone was included. N.B. Some users may be a member of multiple groups which means that duplicates will appear in the array. We will deal with that later.

Now that we have the list of users we want to do two things

  1. We want to check that they have not already been defined explicitly in the ManagedBy attribute along with the security group. If they have we don’t want to add them again and cause a duplication failure.
  2. We want to add the rest of the users to a new list that we will then re-add back to update and replace the current settings.

Ok so we now have a new list. But what about those people that were identified as “users” instead of “groups” in the first part of the script? We haven’t forgotten about them. We have an else statement that captures these objects.

As you can see these users who were added already to the ManagedBy attribute through Exchange are being captured in their own array. We will use this array last in our script.

Now for the fun part of the script where we put it all together.

As I said earlier using the recursive switch can lead to duplication’s.  Adding to an array in PowerShell is easy. Removing elements from an array not so much. The easiest way to achieve this is to actual pipe it to another array using some filtering to remove unwanted elements. In this case piping through a Select statement using the -Unique switch did the job very nicely.

$FinalList = $NewOwnersList | select -Unique

Here is the important command that all the other parts was getting to.

Set-DistributionGroup -BypassSecurityGroupManagerCheck -ManagedBy $FinalList -Identity $DLName

By running this we now replace all the values in the ManagedBy attribute with the new list of users for that Distribution Group. The last thing is to re-add the original user objects that were stored in the $ExistingUser variable. To do this without completely wiping what we just did we pass it through one more loop this time using the Set-DistributionGroup commandlet with the Add feature.

Set-DistributionGroup -Identity $DLName -BypassSecurityGroupManagerCheck -ManagedBy @{ Add = $Exuser }

And there you have it! Future updates of the script will include parameters for inputting plus a reporting feature.

Why this work flow?

When attempting to use the Set-DistributionGroup -Managedby @{Remove=$Variable} for the groups it would throw an error about incorrect types. It was easier to just replace the entire contents with an array and then add the missing ones.

Facebooktwittergoogle_plusby feather
Facebookby feather