@@ -47,7 +47,10 @@ function Push-ExecOnboardTenantQueue {
4747 @ { Name = ' SharePoint Administrator' ; Id = ' f28a1f50-f6e7-4571-818b-6a12f2af6b6c' },
4848 @ { Name = ' Authentication Policy Administrator' ; Id = ' 0526716b-113d-4c15-b2c8-68e3c22b9f80' },
4949 @ { Name = ' Privileged Role Administrator' ; Id = ' e8611ab8-c189-46e8-94e1-60213ab1f814' },
50- @ { Name = ' Privileged Authentication Administrator' ; Id = ' 7be44c8a-adaf-4e2a-84d6-ab2649e08a13' }
50+ @ { Name = ' Privileged Authentication Administrator' ; Id = ' 7be44c8a-adaf-4e2a-84d6-ab2649e08a13' },
51+ @ { Name = ' Billing Administrator' ; Id = ' b0f54661-2d74-4c50-afa3-1ec803f12efe' ; Optional = $true },
52+ @ { Name = ' Global Reader' ; Id = ' f2ef992c-3afb-46b9-b7cf-a126ee74c451' ; Optional = $true },
53+ @ { Name = ' Domain Name Administrator' ; Id = ' 8329153b-31d0-4727-b945-745eb3bc5f31' ; Optional = $true }
5154 )
5255
5356 if ($OnboardingSteps.Step1.Status -ne ' succeeded' ) {
@@ -99,14 +102,16 @@ function Push-ExecOnboardTenantQueue {
99102 }
100103 if (($MissingRoles | Measure-Object ).Count -gt 0 ) {
101104 $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = ' Missing roles for relationship' })
102- if ($Item.IgnoreMissingRoles -ne $true ) {
105+ $RequiredMissingRoles = $ExpectedRoles | Where-Object { $_.Optional -ne $true -and $MissingRoles -contains $_.Name }
106+ if ($Item.IgnoreMissingRoles -ne $true -and ($RequiredMissingRoles | Measure-Object ).Count -gt 0 ) {
107+ $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = " Missing the following required roles: $ ( $MissingRoles -join ' , ' ) " })
103108 $TenantOnboarding.Status = ' failed'
104109 $OnboardingSteps.Step2.Status = ' failed'
105110 $OnboardingSteps.Step2.Message = " Your GDAP relationship is missing the following roles: $ ( $MissingRoles -join ' , ' ) "
106111 } else {
107112 $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = ' Ignoring missing roles' })
108113 $OnboardingSteps.Step2.Status = ' succeeded'
109- $OnboardingSteps.Step2.Message = ' Your GDAP relationship is missing some roles, but the onboarding will continue'
114+ $OnboardingSteps.Step2.Message = " Your GDAP relationship is missing some roles, but the onboarding will continue. Missing roles: $ ( $MissingRoles -join ' , ' ) "
110115 }
111116 } else {
112117 $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = ' Required roles found' })
@@ -121,6 +126,7 @@ function Push-ExecOnboardTenantQueue {
121126 if ($OnboardingSteps.Step2.Status -eq ' succeeded' ) {
122127 $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = ' Checking group mapping' })
123128 $AccessAssignments = New-GraphGetRequest - Uri " https://graph.microsoft.com/beta/tenantRelationships/delegatedAdminRelationships/$Id /accessAssignments"
129+ $AccessAssignments = $AccessAssignments | Where-Object { $_.status -notin @ (' deleted' , ' deleting' ) }
124130 if ($AccessAssignments.id -and $Item.AutoMapRoles -ne $true ) {
125131 $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = ' Groups mapped' })
126132 $OnboardingSteps.Step3.Status = ' succeeded'
@@ -223,6 +229,7 @@ function Push-ExecOnboardTenantQueue {
223229
224230 do {
225231 $AccessAssignments = New-GraphGetRequest - Uri " https://graph.microsoft.com/beta/tenantRelationships/delegatedAdminRelationships/$Id /accessAssignments"
232+ $AccessAssignments = $AccessAssignments | Where-Object { $_.status -notin @ (' deleted' , ' deleting' ) }
226233 Start-Sleep - Seconds 15
227234 } while ($AccessAssignments.status -contains ' pending' -and (Get-Date ) -lt $Start.AddMinutes (8 ))
228235
@@ -231,19 +238,58 @@ function Push-ExecOnboardTenantQueue {
231238 $OnboardingSteps.Step3.Status = ' succeeded'
232239
233240 $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = ' Checking for missing groups for SAM user' })
234- $SamUserId = (New-GraphGetRequest - uri " https://graph.microsoft.com/beta/me?`$ select=id" - NoAuthCheck $true ).id
235- $CurrentMemberships = New-GraphGetRequest - uri " https://graph.microsoft.com/beta/me/transitiveMemberOf?`$ select=id,displayName" - NoAuthCheck $true
236- $ExpectedCippRoles = $Item.Roles | Where-Object { $_.roleDefinitionId -in $ExpectedRoles.roleDefinitionId }
241+ $BulkRequests = @ (
242+ @ {
243+ id = ' samUserId'
244+ method = ' GET'
245+ url = " /me?`$ select=id"
246+ },
247+ @ {
248+ id = ' currentMemberships'
249+ method = ' GET'
250+ url = " /me/transitiveMemberOf?`$ select=id,displayName"
251+ }
252+ )
253+ $BulkResults = New-GraphBulkRequest - Requests $BulkRequests - NoAuthCheck $true
254+ $SamUserId = ($BulkResults | Where-Object { $_.id -eq ' samUserId' }).body.id
255+ $CurrentMemberships = ($BulkResults | Where-Object { $_.id -eq ' currentMemberships' }).body.value
256+ $ExpectedCippRoles = $Item.Roles | Where-Object { $_.roleDefinitionId -in $ExpectedRoles.Id }
257+
258+ # Build bulk requests for missing group memberships
259+ $GroupMembershipRequests = [System.Collections.Generic.List [object ]]::new()
260+ $GroupMembershipLogs = [System.Collections.Generic.List [object ]]::new()
261+
237262 foreach ($Role in $ExpectedCippRoles ) {
238263 if ($CurrentMemberships.id -notcontains $Role.GroupId ) {
239- $PostBody = @ {
240- ' @odata.id' = ' https://graph.microsoft.com/v1.0/directoryObjects/{0}' -f $SamUserId
241- } | ConvertTo-Json - Compress
242- try {
243- New-GraphPostRequest - uri " https://graph.microsoft.com/beta/groups/$ ( $Role.GroupId ) /members/`$ ref" - body $PostBody - AsApp $true - NoAuthCheck $true
244- $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = " Added SAM user to $ ( $Role.GroupName ) " })
245- } catch {
246- $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = " Failed to add SAM user to $ ( $Role.GroupName ) - $ ( $_.Exception.Message ) " })
264+ $GroupMembershipRequests.Add (@ {
265+ id = " addSamUser-$ ( $Role.GroupId ) "
266+ method = ' POST'
267+ url = " groups/$ ( $Role.GroupId ) /members/`$ ref"
268+ body = @ {
269+ ' @odata.id' = ' https://graph.microsoft.com/v1.0/directoryObjects/{0}' -f $SamUserId
270+ }
271+ headers = @ {
272+ ' Content-Type' = ' application/json'
273+ }
274+ })
275+ $GroupMembershipLogs.Add (@ {
276+ id = " addSamUser-$ ( $Role.GroupId ) "
277+ GroupName = $Role.GroupName
278+ })
279+ }
280+ }
281+
282+ # Execute bulk group membership additions if any are needed
283+ if ($GroupMembershipRequests.Count -gt 0 ) {
284+ $GroupMembershipResults = New-GraphBulkRequest - Requests $GroupMembershipRequests - AsApp $true - NoAuthCheck $true
285+
286+ foreach ($LogEntry in $GroupMembershipLogs ) {
287+ $Result = $GroupMembershipResults | Where-Object { $_.id -eq $LogEntry.id }
288+ if ($Result.status -match ' ^2[0-9]+' ) {
289+ $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = " Added SAM user to $ ( $LogEntry.GroupName ) " })
290+ } else {
291+ $ErrorMessage = if ($Result.body.error.message ) { $Result.body.error.message } else { ' Unknown error' }
292+ $Logs.Add ([PSCustomObject ]@ { Date = (Get-Date ).ToUniversalTime(); Log = " Failed to add SAM user to $ ( $LogEntry.GroupName ) - $ErrorMessage " })
247293 }
248294 }
249295 }
0 commit comments