After yet another manual update of membership in a Teams-site I decided to Powershell it once for all.
Here are my notes on how to synchronize the AD Security Group Membership with the (beta) Powershell Cmdlets (and the actual function for it).
Basically this will let you synchronize AD-group members with a Team with a single Powershell-function.
Prerequisites / read first
The prerequisites are Powershell Cmdlets for connecting to Teams & MSOnline and an Admin account. If you need more information on how to connect and some more notes about the limitation of the current Cmdlets check out my post about Managing Microsoft Teams with Powershell.
Getting the information we need from Azure AD
The simplest way is (almost) always the best. For our user-case it's getting the AAD-group members and save their UPN to be used for synchronizing the membership with Teams by adding and/or removing members. This approach will also let us automate stuff in the future by for instance using an Azure Automation Runbook.
The first input for the function will therefore be an Azure AD Group (in our case a synced group).
The second input will be the actual Team. Since Teams membership is
based on the same as the Office 365 group membership we can pick between using the actual Teams cmdlets and the good old Exchange
Add-UnifiedGroupLinks. I'll be using the Teams cmdlets since they are all new and shiny ;).
So let's script
Finally it's time to make the full Powershell function to synchronize an Azure AD-group with Teams.
First thing we need to get is the actual members in the security group and the Team group to see if we have any changes. First I was thinking about using
LastDirsyncTime to look for changes but since the AAD-group can be an O365 group only I decided to just compare members.
To get members without connecting to Exchange Online I use
Get-MsolGroupMember. This cmdlet needs a GroupObjetID so the first step will be to get this ID for the AAD and Team group. The second step is to get all the members for those ID's:
As you can see I've also added some basic error handling, such as if no group or more than 1 group is found.
Now that we have two objects containing all AAD and Team members we need a good way to compare them. Powershell has a cmdlet for this built-in called
Compare-Object. I cannot recommend this one, it's slow and not very well implemented. Instead an old colleague of mine taught me about HashSets and the improved speed you get with the .NET method ExceptWith. So for this function I made a (somewhat) general comparison helper function Compare-Arrays:
This function will output an array with
RemoveFromReference which will contain a list with members to add or remove to the Team and I will use it like this:
$Comparison = Compare-Arrays -Reference $AADGroupMembers.ObjectId -Difference $TeamGroupMembers.ObjectId
Now the fun part starts, the actual synchronization-loop:
Note that I also added support for the
$OnlyAdd switch we used as an input.
This all together will result in the following function: https://github.com/selevik/a.random.name/blob/master/Sync-ADGroupWithTeams/Sync-AADGroupMembersWithTeam.ps1.
To use it all you have to do is to load the function .\Sync-ADGroupWithTeams.ps1 and then:
Sync-AADGroupMembersWithTeams -TeamName 'A Random Name' -AADGroupName 'aRandomGroup'
If you use:
Sync-AADGroupMembersWithTeams -TeamName 'A Random Name' -AADGroupName 'aRandomGroup' -Cred $Credentials you can use the exported credentials you've saved from this post: Some neat Powershell-snippets for connecting to Office 365 and Exchange Online (and managing credentials) and voila. You have yourself a schedule task for keeping your teams up-to-date!