In this post, I present a PowerShell script to synchronize the membership between security groups and Office 365 groups.
Security groups in Azure Active Directory (AAD) have long been a useful way to manage sets of users in the enterprise -- even going back to on-premises Active Directory and before that, Windows NT global groups. The Office 365 Groups service is the more modern way to address this need, used by Microsoft Teams, Planner, Outlook Groups, Yammer, Power BI, and more. Of course, they're not connected (yet), which is unfortunate but not atypical given the evolution of platforms and products and sometimes divergent scenarios.
Many companies use AAD security groups extensively, for good reason, and they have a lot of intellectual capital vested in the creation, curation, and management of those security groups. At Microsoft we've used security groups to manage access to internal support resources, bug databases, and source code systems. These companies logically want to leverage their security groups investment for Microsoft Teams and other Office 365 Groups-based services, but they can't right now. If you add a security group to a team membership list, Teams will do a one-time expansion of the security group (same for a distribution list), but any subsequent changes are not reflected in the team, and vice versa.
Obviously, a great solution would be to base the team membership directly on a security group, so that any changes to the security group are reflected in the team in Microsoft Teams, and vice versa. This would be similar to how Teams leverages the Office 365 Groups service. The engineering team is aware of this request and it is marked as on the backlog. You can provide additional input on the use case and priority via the User Voice feedback system, item 1861385. Similar user feedback has also been provided to the Office 365 Groups team, and you can read and vote on their feedback system too, item 33942997.
But while we wait for those engineering teams to get to this work (and deal with a thousand other demands on their time), let's take a look at a short-term solution that will unblock companies looking to synchronize security group membership with team membership.
The premise is straightforward: create a PowerShell script that will run periodically, maybe every 12 hours or 24 hours, which synchronizes one or more pairs of security group/Office 365 group. Now, the PowerShell interfaces are a little different for each type of group (see note above re: platform evolution and divergent scenarios), but with a little hacking and slashing, I got it to work reasonably well.
BIG WARNING: I was a physics major in college who fell backwards into software product management. I'm not a developer, and only sort of an "engineer" (in Canada, they probably wouldn't let me wear the pinky ring). My coding process involves a lot of trial-and-error mixed with Stack Overflow research. This code should not be considered production-ready. Rather, look at it as an illustrated proof-of-concept that actual real developers can use to build actual real code.
The source code is on GitHub, naturally: https://github.com/danspot/Danspot-Scripts-and-Samples-Emporium
Here's roughly what the script does:
In this diagram, you can see how one user ("Rajesh") is in the AAD security group but not the Office 365 group, so that user should be added to the latter. And another user, "Stewart" is in the Office 365 group but not the security group, so that user should be removed. Bye Stewart!
Here's the key part of the code that scans the security group and adds missing members (in a brute force way) to the Office 365 group:
# loop through all Security Group members and add them to a list
# might be more efficient (from a service API perspective) to have an inner foreach
# loop that verifies the user is not in the O365 Group
Write-Output "Loading list of Security Group members"
$securityGroupMembersToAdd = New-Object System.Collections.ArrayList
foreach ($securityGroupMember in $securityGroupMembers)
{
$memberType = $securityGroupMember.GroupMemberType
if ($memberType -eq 'User') {
$memberEmail = $securityGroupMember.EmailAddress
$securityGroupMembersToAdd.Add($memberEmail)
}
}
# add all the Security Group members to the O365 Group
# this is not super efficient - might be better to remove any existing members first
# this might need to be broken into multiple calls depending on API limitations
Write-Output "Adding Security Group members to O365 Group"
Add-UnifiedGroupLinks -Identity $O365GroupID -LinkType Members -Links $securityGroupMembersToAdd
And here's the part of the code that removes users who are in the Office 365 group but not the security group. Probably the trickiest part of the script was finding and aligning the user ID between the two different groups schemas.
# loop through the O365 Group and remove anybody who is not in the security group Write-Output "Looking for O365 Group members who are not in Security Group" $O365GroupMembersToRemove = New-Object System.Collections.ArrayList foreach ($O365GroupMember in $O365GroupMembers) { $userFound = 0 foreach ($emailAddress in $O365GroupMember.EmailAddresses) { # trim the protocol ("SMTP:") $emailAddress = $emailAddress.substring($emailAddress.indexOf(":")+1,$emailAddress.length-$emailAddress.indexOf(":")-1) if ($securityGroupMembersToAdd.Contains($emailAddress)) { $userFound = 1 } } if ($userFound -eq 0) { $O365GroupMembersToRemove.Add($O365GroupMember) } } if ($O365GroupMembersToRemove.Count -eq 0) { Write-Output " ...none found" } else { # remove members Write-Output " ... removing $O365GroupMembersToRemove" foreach ($memberToRemove in $O365GroupMembersToRemove) { Remove-UnifiedGroupLinks -Identity $O365GroupID -LinkType Members -Links $memberToRemove.name } }
Important notes:
And there you go! Use the comments to let me know how it works, suggest improvements, link to your own solutions, and more. Just remember not to add Stewart to any of your teams.
About the author: Dan Stevenson was one of the early creators of Microsoft Teams. He led the product management team behind key features like teams and channels, guest access, Teams for education, and the free version of Teams. He recently moved with his family to Taipei, Taiwan, where he leads Teams customer engineering for the Asia Pacific region.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.