By using PowerShell, you can keep on-premise Active Directory groups (security or distribution) synced to Office 365 Groups and Microsoft Teams.
Microsoft has been working on a native group syncing tool for a few years. As of the current date, circa 1 AC[note]After Covid[/note], this tool is still in development. You can check the status of it here. The release date has changed several times so don’t get too attached to it.
The PowerShell script, below, will let you sync your on-premise groups to your Azure / Microsoft 365 groups. Most of this script came from this Microsoft Teams blog.
To use it, set the $O365User and $O365Password variables to a user that has permission to update group memberships in Office 365[note]Or store the credentials in an encrypted file and call that.[/note]. You will also need to set ‘@DOMAIN.COM’ on line 54.
When you run the script, it will look at every AD group in your environment[note]You can exclude groups by editing the filter on line 18[/note] and compare their name against unified groups. If the name matches, it will sync group membership (add/remove group members) from the unified group in Azure.
One final note. When setting this script to run automatically, limit it to once or so a day. If it runs more than that, Outlook will show incorrect group membership counts to users.
$O365User = "USERNAME@DOMAIN.COM"
$O365Password = ConvertTo-SecureString -string "PASSWORDFORUSER" -AsPlainText -force
$O365Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $O365User,$O365Password
# get credentials and login as Exchange admin and PS Session (remember to close session later)
$ExchangeCred = $O365Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $ExchangeCred -Authentication Basic -AllowRedirection
Import-PSSession $Session -DisableNameChecking -AllowClobber
# get credentials and login as AAD admin
$AADCred =$O365Credential
Connect-MsolService -Credential $AADCred
#Get List of Non School Data Sync Groups from O365 and AD
$Groups = Get-UnifiedGroup -ResultSize Unlimited | ? {$_.PrimarySmtpAddress -notlike "Section_*"}
$ADGroups = get-adgroup -Filter *
#Cycle Through Groups - Compare to AD - Add/Remove Users from O365
foreach ($Group in $Groups){
$GroupDisplayName = $Group.DisplayName
if (($ADGroups | where Name -eq $GroupDisplayName) -ne $Null){
Write-Host $GroupDisplayName
#pause
# get name of O365 Group to look up
$O365GroupName = "$GroupDisplayName"
# get name of Security Group to look up
$securityGroupName = "$GroupDisplayName"
# get O365 Group ID
### you can do this via AAD as well: $O365Group = Get-MsolGroup | Where-Object {$_.DisplayName -eq $O365GroupName}
$O365Group = Get-UnifiedGroup -Identity $O365GroupName
$O365GroupID = $O365Group.ID
Write-Output "O365 Group ID: $O365GroupID"
# get list of O365 Group members
### you can do this via AAD as well: $O365GroupMembers = Get-MsolGroupMember -GroupObjectId $O365GroupID
$O365GroupMembers = Get-UnifiedGroupLinks -Identity $O365GroupID -LinkType subscribers -ResultSize unlimited
# get list of Security Group members
$securityGroupMembers = Get-ADGroupMember -Identity $securityGroupName -Recursive
# loop through all Security Group members and add them to a list
Write-Output "Loading list of Security Group members"
$securityGroupMembersToAdd = New-Object System.Collections.ArrayList
foreach ($securityGroupMember in $securityGroupMembers)
{
$memberType = $securityGroupMember.objectClass
if ($memberType -eq 'User') {
$memberEmail = $securityGroupMember.SamAccountName + '@DOMAIN.COM'
$securityGroupMembersToAdd.Add($memberEmail)
}
}
# add all the Security Group members to the O365 Group
Write-Output "Adding Security Group members to O365 Group"
Add-UnifiedGroupLinks -Identity $O365GroupID -LinkType members -Links $securityGroupMembersToAdd
Add-UnifiedGroupLinks -Identity $O365GroupID -LinkType subscribers -Links $securityGroupMembersToAdd
# 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) {
Write-Host $emailAddress
#pause
$emailAddress = $emailAddress.substring($emailAddress.indexOf(":")+1,$emailAddress.length-$emailAddress.indexOf(":")-1)
Write-Host $EmailAddress
if ($securityGroupMembersToAdd -icontains($emailAddress)) { $userFound = 1 }
}
if ($userFound -eq 0) { $O365GroupMembersToRemove.Add($O365GroupMember)
#pause
}
}
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 subscribers -Links $memberToRemove.name -Confirm:$false
Remove-UnifiedGroupLinks -Identity $O365GroupID -LinkType members -Links $memberToRemove.name -Confirm:$false
}
}
}
}
# close the Exchange session
Remove-PSSession $Session
Write-Output "Done. Thanks for playing."
Hi thanks for the knowledge transfer. I’m struggling to sync multiple AAD security groups to a single m365 group. Particularly in deleting user from m365 group when AAD sec group membership revoked.
Hi and thanks for the script. I am looking for a way to update Teams “teams” membership with security groups and wondering if I could tailor this script for that. Basically, I create a team called “IT APAC”, I want to use a security group to manage membership to it. So not sure if I can use this script to scan an on-prem security group and add/remove users in the security group to the teams M365 group in AAD.
This script will do just that without modification. A Teams “team” is effectively a Unified Group aka Microsoft Group.
Is is also possible to sync with Security Groups instead of O365 Groups?