Syncing the Users between the groups in Azure AD using PowerShell

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, 

User Group Tree

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. 


Similar Articles