From 8b4845854599d2979adab56c65aeebfbaf5ce66c Mon Sep 17 00:00:00 2001 From: haydarkozat Date: Sat, 29 Aug 2026 16:19:13 +0300 Subject: [PATCH] feat: add department group assignment script --- .../Set-DepartmentGroupMemberships.ps1 | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 enterprise-lab/scripts/Set-DepartmentGroupMemberships.ps1 diff --git a/enterprise-lab/scripts/Set-DepartmentGroupMemberships.ps1 b/enterprise-lab/scripts/Set-DepartmentGroupMemberships.ps1 new file mode 100644 index 0000000..4c7215c --- /dev/null +++ b/enterprise-lab/scripts/Set-DepartmentGroupMemberships.ps1 @@ -0,0 +1,100 @@ +[CmdletBinding(SupportsShouldProcess = $true, ConfirmImpact = 'Medium')] +param( + [Parameter(Mandatory)] + [ValidateScript({ Test-Path -LiteralPath $_ })] + [string]$CsvPath +) + +$ErrorActionPreference = 'Stop' + +foreach ($moduleName in @('Microsoft.Graph.Users', 'Microsoft.Graph.Groups')) { + if (-not (Get-Module -ListAvailable -Name $moduleName)) { + throw "Required module '$moduleName' is not installed. Install-Module Microsoft.Graph -Scope CurrentUser" + } +} + +Import-Module Microsoft.Graph.Users +Import-Module Microsoft.Graph.Groups + +$context = Get-MgContext +if (-not $context) { + throw 'No Microsoft Graph session found. Connect first.' +} + +$rows = @(Import-Csv -LiteralPath $CsvPath) +if ($rows.Count -eq 0) { + throw 'CSV contains no users.' +} + +$results = foreach ($row in $rows) { + $upn = [string]$row.UserPrincipalName + $department = [string]$row.Department + + if ([string]::IsNullOrWhiteSpace($upn) -or [string]::IsNullOrWhiteSpace($department)) { + [pscustomobject]@{ + UserPrincipalName = $upn + Department = $department + Group = $null + Status = 'Skipped' + Reason = 'Missing UPN or Department.' + } + continue + } + + $groupName = "SG-Dept-$department" + $escapedUpn = $upn.Replace("'", "''") + $escapedGroup = $groupName.Replace("'", "''") + + $user = Get-MgUser -Filter "userPrincipalName eq '$escapedUpn'" -Property Id, UserPrincipalName + if (-not $user) { + [pscustomobject]@{ + UserPrincipalName = $upn + Department = $department + Group = $groupName + Status = 'Skipped' + Reason = 'User not found.' + } + continue + } + + $group = Get-MgGroup -Filter "displayName eq '$escapedGroup'" -Property Id, DisplayName + if (-not $group) { + [pscustomobject]@{ + UserPrincipalName = $upn + Department = $department + Group = $groupName + Status = 'Skipped' + Reason = 'Department group not found.' + } + continue + } + + $memberIds = @(Get-MgGroupMember -GroupId $group.Id -All | ForEach-Object { $_.Id }) + if ($user.Id -in $memberIds) { + [pscustomobject]@{ + UserPrincipalName = $upn + Department = $department + Group = $groupName + Status = 'Existing' + Reason = 'Membership already exists.' + } + continue + } + + $target = "$upn -> $groupName" + if ($PSCmdlet.ShouldProcess($target, 'Add Microsoft Entra group membership')) { + New-MgGroupMemberByRef -GroupId $group.Id -BodyParameter @{ + '@odata.id' = "https://graph.microsoft.com/v1.0/directoryObjects/$($user.Id)" + } + + [pscustomobject]@{ + UserPrincipalName = $upn + Department = $department + Group = $groupName + Status = 'Added' + Reason = 'Department membership assigned.' + } + } +} + +$results | Sort-Object Group, UserPrincipalName