Powershell - Add users from groups to assign group with group exceptions
Olívio Moura
4 min read
# Ensure the Microsoft.Graph module is imported
# Import-Module Microsoft.Graph
# Authenticate using the managed identity
Connect-MgGraph -Identity -NoWelcome
#Connect-MgGraph -Scopes "User.Read.All", "Group.ReadWrite.All" -NoWelcome
# Control variable to enable/disable output
$EnableOutput = $true # Set to $false to disable output, $true to enable
# Function to control output based on the $EnableOutput flag
function ConditionalWrite-Output {
param (
[string]$Message
)
if ($EnableOutput) {
Write-Output $Message
}
}
# Define the group configurations
$groupConfigs = @(
###################### ZOOM ######################
@{
IdentitySource = @("SourceGroup1","SourceGroup2","SourceGroup3")
IdentityAssignGroup = "AssignGroup"
IdentityAssignGroupLimit = 1850
IdentityAssignSoftLimitNew = 10
IdentityAssignSoftLimitRemove = 5
IdentityAssignHardLimitRemove = 50
IdentityExclusion = @("ExclusionGroup1")
}
)
foreach ($config in $groupConfigs) {
# Extract group-specific values
$IdentityAssignGroup = $config.IdentityAssignGroup
$IdentityAssignGroupLimit = $config.IdentityAssignGroupLimit
$IdentityAssignSoftLimitNew = $config.IdentityAssignSoftLimitNew
$IdentityAssignSoftLimitRemove = $config.IdentityAssignSoftLimitRemove
$IdentityAssignHardLimitRemove = $config.IdentityAssignHardLimitRemove
$IdentityExclusion = $config.IdentityExclusion
$IdentitySource = $config.IdentitySource
# Retrieve the assign group by its display name
$groupIdentityAssign = Get-MgGroup -Filter "displayName eq '$IdentityAssignGroup'"
if ($null -eq $groupIdentityAssign) {
throw "Group '$IdentityAssignGroup' not found."
}
# Retrieve members of the assign group
$membersIdentityAssign = Get-MgGroupMember -GroupId $groupIdentityAssign.Id -All:$true | Select-Object -Property Id
# Create hash set for fast lookup of assign group members
$assignMemberIds = @{}
$membersIdentityAssign | ForEach-Object { $assignMemberIds[$_.Id] = $true }
# Initialize current group size
$currentGroupSize = $assignMemberIds.Count
# Combine members from all exclusion groups
$exclusionMemberIds = @{}
foreach ($exclusionGroup in $IdentityExclusion) {
$groupIdentityExclusion = Get-MgGroup -Filter "displayName eq '$exclusionGroup'"
if ($null -eq $groupIdentityExclusion) {
throw "Exclusion group '$exclusionGroup' not found."
}
$membersIdentityExclusion = Get-MgGroupMember -GroupId $groupIdentityExclusion.Id -All:$true | Select-Object -Property Id
$membersIdentityExclusion | ForEach-Object { $exclusionMemberIds[$_.Id] = $true }
}
# Identify unique members to remove (intersection of assign group and exclusion group)
$membersToRemove = $assignMemberIds.Keys | Where-Object { $exclusionMemberIds[$_] } | Select-Object -Unique
# Check if the number of members to remove will exceed the hard limit
if ($membersToRemove.Count -gt $IdentityAssignHardLimitRemove -and $IdentityAssignHardLimitRemove -ne 0) {
ConditionalWrite-Output "The number of members to remove ($($membersToRemove.Count)) exceeds the hard limit of $IdentityAssignHardLimitRemove. No members will be removed from group '$IdentityAssignGroup'."
} else {
# Remove members until the soft limit is reached
$removalCount = 0
foreach ($memberId in $membersToRemove) {
if ($currentGroupSize -le $IdentityAssignSoftLimitRemove -and $IdentityAssignSoftLimitRemove -ne 0) {
ConditionalWrite-Output "Reached the soft limit of $IdentityAssignSoftLimitRemove members for group '$IdentityAssignGroup'. No more members will be removed."
break
}
Remove-MgGroupMemberByRef -GroupId $groupIdentityAssign.Id -DirectoryObjectId $memberId
ConditionalWrite-Output "Removed member with Id '$((Get-MgUser -UserId $memberId).UserPrincipalName)' from group '$IdentityAssignGroup'"
# Update hash table and current group size
$assignMemberIds.Remove($memberId)
$currentGroupSize -= 1
$removalCount += 1
}
ConditionalWrite-Output "Completed removal of excluded members for group '$IdentityAssignGroup'."
}
# Initialize a collection for the combined members from all source groups
$membersIdentitySourceCombined = @()
# Retrieve and combine members from each source group
foreach ($sourceGroup in $IdentitySource) {
$groupIdentitySource = Get-MgGroup -Filter "displayName eq '$sourceGroup'"
if ($null -eq $groupIdentitySource) {
throw "Source group '$sourceGroup' not found."
}
$membersIdentitySource = Get-MgGroupMember -GroupId $groupIdentitySource.Id -All:$true | Select-Object -Property Id
$membersIdentitySourceCombined += $membersIdentitySource
}
# Ensure membersIdentitySourceCombined is unique before shuffling
$membersIdentitySourceCombined = $membersIdentitySourceCombined | Select-Object -Unique -Property Id
# Shuffle the combined list of unique source members to ensure randomness
$membersIdentitySourceCombined = $membersIdentitySourceCombined | Get-Random -Count $membersIdentitySourceCombined.Count
# Add matching users from the combined source groups to $groupIdentityAssign until the limit is reached
$additionCount = 0
foreach ($user in $membersIdentitySourceCombined) {
if ($IdentityAssignGroupLimit -ne 0 -and $currentGroupSize -ge $IdentityAssignGroupLimit) {
ConditionalWrite-Output "Reached the overall limit of $IdentityAssignGroupLimit members for group '$IdentityAssignGroup'."
break
}
if ($IdentityAssignSoftLimitNew -ne 0 -and $additionCount -ge $IdentityAssignSoftLimitNew) {
ConditionalWrite-Output "Reached the addition limit of $IdentityAssignSoftLimitNew members for group '$IdentityAssignGroup'."
break
}
# Skip if the user is in the exclusion group
if ($exclusionMemberIds.ContainsKey($user.Id)) {
#ConditionalWrite-Output "Skipped user '$((Get-MgUser -UserId $user.Id).UserPrincipalName)' because they are in the exclusion group(s): $($IdentityExclusion -join ', ')."
continue
}
# Add user to the group if not already present
if (-not $assignMemberIds.ContainsKey($user.Id)) {
New-MgGroupMember -GroupId $groupIdentityAssign.Id -DirectoryObjectId $user.Id
ConditionalWrite-Output "Added user '$((Get-MgUser -UserId $user.Id).UserPrincipalName)' to group '$IdentityAssignGroup'"
# Update hash table and current group size
$assignMemberIds[$user.Id] = $true
$currentGroupSize += 1
$additionCount += 1
}
}
ConditionalWrite-Output "Script execution completed for group '$IdentityAssignGroup'."
}
# Disconnect from Microsoft Graph
Disconnect-MgGraph | Out-Null
0
Subscribe to my newsletter
Read articles from Olívio Moura directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by