Introduction
In this article, you will learn how to sync the user between a nested group and another destination group in Azure AD using the Azure PowerShell script. Azure PowerShell is used to manage the Azure resources from the command line. Basically, the Azure PowerShell scripts are developed to automate the process.
Get Started with Azure PowerShell
To get started with Azure PowerShell in your Windows machine, install the Az PowerShell Module using the below command with PowerShell.
Install-Module -Name Az -Repository PSGallery -Force
Once the installation is done, please use the below statement to connect with your Azure account.
Connect-AzAccount
Consider below user group hierarchy,
The Test Flat is the root group in our AD, and We have nested groups like Finacs-dev, Finace- Finacs-Sub Manager, and I have one user group called “All User Group” which is my destination group.
Now we need to sync the users between the nested group and with the destination group, which means getting the collection of all users from the nested group, and comparing it with the destination group user list, If the user is not found in the destination group add it or remove the user from the destination group which is not there in user collections from the nested group.
# Function to retrieve all nested groups
function Get-NestedGroups {
param(
[Parameter(Mandatory = $true)]
[string]$GroupId
)
$group = Get-AzureADGroup -ObjectId $GroupId
$nestedGroups = Get-AzureADGroupMember -ObjectId $GroupId | Where-Object {$_.ObjectType -eq "Group"}
foreach ($nestedGroup in $nestedGroups) {
$nestedGroupId = $nestedGroup.ObjectId
Get-NestedGroups -GroupId $nestedGroupId
}
$nestedGroups
}
The above script will get the nested group list
# Get all groups in Azure Active Directory
$groups = Get-AzureADGroup -All $true
# Array to store all user members
$sourceUsers = @()
foreach ($group in $groups) {
$groupId = $group.ObjectId
$nestedGroups = Get-NestedGroups -GroupId $groupId
foreach ($nestedGroup in $nestedGroups) {
$groupMembers = Get-AzureADGroupMember -ObjectId $nestedGroup.ObjectId | Where-Object {$_.ObjectType -eq "User"}
if($sourceUsers -notcontains $groupMembers){
$sourceUsers += $groupMembers
}
}
}
Write-Host "------------------Source user list-------------------------"
# Display the user members
$sourceUsers | Select-Object -Property ObjectId, UserPrincipalName, DisplayName
The above script will fetch the user list from the nested groups
Write-Host "------------------Destination user list-------------------------"
# Destination user list
# Group name or Group ID
$groupName = "All User Group"
# Get the group
$destinationGroup = Get-AzureADGroup -Filter "DisplayName eq '$groupName'"
# Array to store all user members
$destinationUsers= @()
if ($destinationGroup) {
# Get the members of the group
$destinationUsers = Get-AzureADGroupMember -ObjectId $destinationGroup.ObjectId | Where-Object {$_.ObjectType -eq "User"}
# Display the user members
$destinationUsers | Select-Object -Property ObjectId, UserPrincipalName, DisplayName
} else {
Write-Host "Group '$groupName' not found."
}
The above script will use to fetch the user list from the destination group.
# Get the existing user object IDs in the destination group
$existingUserObjectIds = $destinationUsers | Where-Object { $_.ObjectType -eq "User" } | Select-Object -ExpandProperty ObjectId
# Loop through destination group members
foreach ($destinationUser in $destinationUsers) {
# Check if the member is a user and if it doesn't exist in the source group
if ($destinationUser.ObjectType -eq "User" -and $sourceUsers.ObjectId -notcontains $destinationUser.ObjectId) {
# Remove the user from the destination group
Remove-AzureADGroupMember -ObjectId $destinationGroup.ObjectId -MemberId $destinationUser.ObjectId
# Display a message for the removed user
Write-Host "Removed User $($destinationUser.ObjectId) from Destination Group."
}
}
# Loop through source group members
foreach ($sourceUser in $sourceUsers) {
# Check if the member is a user and if it doesn't exist in the destination group
if ($sourceUser.ObjectType -eq "User" -and $existingUserObjectIds -notcontains $sourceUser.ObjectId) {
# Add the user to the destination group
Add-AzureADGroupMember -ObjectId $destinationGroup.ObjectId -RefObjectId $sourceUser.ObjectId
# Display a message for the added user
Write-Host "Added User $($sourceUser.ObjectId) to Destination Group."
}
}
The above script iterates the collection of all users from the nested group and compares it with the destination group user list, If the user is not found in the destination group, add it or remove the user from the destination group which is not there in the user collections from the nested group.
Complete Script
# Connect to Azure Active Directory
Connect-AzureAD
# Function to retrieve all nested groups
function Get-NestedGroups {
param(
[Parameter(Mandatory = $true)]
[string]$GroupId
)
$group = Get-AzureADGroup -ObjectId $GroupId
$nestedGroups = Get-AzureADGroupMember -ObjectId $GroupId | Where-Object {$_.ObjectType -eq "Group"}
foreach ($nestedGroup in $nestedGroups) {
$nestedGroupId = $nestedGroup.ObjectId
Get-NestedGroups -GroupId $nestedGroupId
}
$nestedGroups
}
# Get all groups in Azure Active Directory
$groups = Get-AzureADGroup -All $true
# Array to store all user members
$sourceUsers = @()
foreach ($group in $groups) {
$groupId = $group.ObjectId
$nestedGroups = Get-NestedGroups -GroupId $groupId
foreach ($nestedGroup in $nestedGroups) {
$groupMembers = Get-AzureADGroupMember -ObjectId $nestedGroup.ObjectId | Where-Object {$_.ObjectType -eq "User"}
if($sourceUsers -notcontains $groupMembers){
$sourceUsers += $groupMembers
}
}
}
Write-Host "------------------Source user list-------------------------"
# Display the user members
$sourceUsers | Select-Object -Property ObjectId, UserPrincipalName, DisplayName
Write-Host "------------------Destination user list-------------------------"
# Destination user list
# Group name or Group ID
$groupName = "All User Group"
# Get the group
$destinationGroup = Get-AzureADGroup -Filter "DisplayName eq '$groupName'"
# Array to store all user members
$destinationUsers= @()
if ($destinationGroup) {
# Get the members of the group
$destinationUsers = Get-AzureADGroupMember -ObjectId $destinationGroup.ObjectId | Where-Object {$_.ObjectType -eq "User"}
# Display the user members
$destinationUsers | Select-Object -Property ObjectId, UserPrincipalName, DisplayName
} else {
Write-Host "Group '$groupName' not found."
}
# Get the existing user object IDs in the destination group
$existingUserObjectIds = $destinationUsers | Where-Object { $_.ObjectType -eq "User" } | Select-Object -ExpandProperty ObjectId
# Loop through destination group members
foreach ($destinationUser in $destinationUsers) {
# Check if the member is a user and if it doesn't exist in the source group
if ($destinationUser.ObjectType -eq "User" -and $sourceUsers.ObjectId -notcontains $destinationUser.ObjectId) {
# Remove the user from the destination group
Remove-AzureADGroupMember -ObjectId $destinationGroup.ObjectId -MemberId $destinationUser.ObjectId
# Display a message for the removed user
Write-Host "Removed User $($destinationUser.ObjectId) from Destination Group."
}
}
# Loop through source group members
foreach ($sourceUser in $sourceUsers) {
# Check if the member is a user and if it doesn't exist in the destination group
if ($sourceUser.ObjectType -eq "User" -and $existingUserObjectIds -notcontains $sourceUser.ObjectId) {
# Add the user to the destination group
Add-AzureADGroupMember -ObjectId $destinationGroup.ObjectId -RefObjectId $sourceUser.ObjectId
# Display a message for the added user
Write-Host "Added User $($sourceUser.ObjectId) to Destination Group."
}
}
Summary
We have seen one of the use cases to manage and sync the users between the nested and destination group. By managing the Azure resources with PowerShell script, we can automate the process. Based on the requirement, we can schedule the job with this PowerShell script and trigger it daily or weekly basis to sync the user groups, by this way, this process is automated.