Managing Office 365 Group Membership with PowerShell

Want Dynamic Groups But Don’t Want to Pay for Azure Active Directory Premium Licenses? Here’s How to Do the Job

A reader says that they like the notion of dynamic Office 365 groups, but they don’t want to pay for the Azure Active Directory premium licenses needed to use the feature. As you might recall, dynamic groups have their membership controlled by queries executed against Azure Active Directory. Every account that comes within the scope of a query must be licensed.

Instead of using dynamic groups, our reader is willing to run scheduled background jobs to populate the membership. They need some guidance as to how to approach building the script to manage membership for a group. As an example to help them, this post describes how to manage group membership based on Office location. Our first step is therefore to grab a set of mailboxes with the right value for the Office attribute and store it in a PowerShell variable. Because I’m based in Dublin, I’ll use it as the Office location.

$Mbx = (Get-Mailbox -Filter {Office -eq "Dublin"} -ResultSize Unlimited)

Using the Filter parameter is important because this forces Exchange Online to process the query on the server, and we get the right results faster. That is, if your directory is correctly populated.

Adding Members to an Office 365 Group

To update the membership of an Office 365 group, we use the Add-UnifiedGroupLinks cmdlet. The simplest method is to use the variable holding the set of mailboxes as the input, passing the distinguished name of each mailbox as the link. To test everything, I created a new group called Dublin Employees and then ran this code to populate its membership.

Add-UnifiedGroupLinks -Identity DublinEmployees -LinkType Member -Links $Mbx.DistinguishedName

To check that the correct membership has been added, we can run the Get-UnifiedGroupLinks cmdlet:

Get-UnifiedGroupLinks -Identity DublinEmployees -LinkType Member

Maintaining Membership

All easy so far, but the issue is now how to maintain the membership. We don’t have to worry about deleted mailboxes as they lose membership when they are removed. But we do need to add new employees whose accounts match the filter and remove people who no longer match.

Adding new members is straightforward because we can use the same commands to form a set of matching mailboxes and run the Add-UnifiedGroupLinks command again. Exchange Online will ignore mailboxes that already exist in the membership.

Mailboxes that no longer match can be removed by running the Remove-UnifiedGroupLinks cmdlet. However, we must figure out what members to remove. One way to do this is to check the current membership against the set of mailboxes that should be members and remove any members that no longer qualify. In this code snippet, we create a hash table and populate it with the set of mailboxes (it’s faster to check against a hash table if the membership is large). We then check each of the members in the current membership against the hash table. Any member that isn’t found in the table doesn’t work in the Dublin office, so we go ahead and remove them.

# Remove lingering members from the group after they leave the Dublin office.
$Members = (Get-UnifiedGroupLinks -Identity DublinEmployees -LinkType Member | Select Alias, DistinguishedName, DisplayName)
$MembersHash = @{}
# Populate MembersHash with the current set of mailboxes from the Dublin office
ForEach ($M in $Mbx) {$MembersHash.Add($M.DistinguishedName, $M.Alias) }
# Check each member in the current membership. If they're not in the mailbox hash table, remove them from the membership
ForEach ($Member in $Members) {
  If ($MembersHash.ContainsKey($Member.DistinguishedName) -eq $False) {
     Write-Host "Removing" $Member.DisplayName "from Dublin Employees membership" 
     Remove-UnifiedGroupLinks -Identity DublinEmployees -Linktype Member -Links $Member.Alias -Confirm:$False }

Dealing With Group Owners

One small glitch. Group owners are also members, but a group owner might not belong to the Dublin office. The command fails if you run Remove-UnifiedGroupLinks to remove an owner from the member list without removing them as an owner first. As we don’t want to see any nasty errors, we should incorporate a check for owner status before we try to remove a member. Here’s the change I made to the script.

# Include check for group owners before we delete a member
ForEach ($Member in $Members) {
  If ($MembersHash.ContainsKey($Member.DistinguishedName) -eq $False) {
    If ((Get-UnifiedGroupLinks -id "Dublin Employees" -LinkType Owner | Select Alias) -Match $Member.Alias) {
       Write-Host "Can't remove" $Member.DisplayName "as member - they are group owner." }
    Else {
       Write-Host "Removing" $Member.DisplayName "from Dublin Employees membership" 
       Remove-UnifiedGroupLinks -Identity DublinEmployees -Linktype Member -Links $Member.Alias -Confirm:$False }

Because Teams uses Office 365 Groups to manage the membership of teams, the same approach works for Teams without the need to rewrite to use the cmdlets in the Teams PowerShell module.

More Work to Do

I’m sure other bells and whistles could be added to make the code work the way an organization wants, but that’s not the purpose of this post. I set out to answer the question and give some guidance about the commands used to maintain Office 365 group membership. There’s enough here for serious programmers (more serious than I am) to get their teeth into the problem and craft a production-quality solution.

For more information about using PowerShell to manage Office 365 Groups (and Teams), read the comprehensive chapter in the Office 365 for IT Pros eBook.

Leave a Reply

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