@@ -7,12 +7,9 @@ function Add-CIPPApplicationPermission {
77 $TenantFilter
88 )
99 if ($ApplicationId -eq $env: ApplicationID -and $TenantFilter -eq $env: TenantID ) {
10- # return @('Cannot modify application permissions for CIPP-SAM on partner tenant')
1110 $RequiredResourceAccess = ' CIPPDefaults'
1211 }
13- Set-Location (Get-Item $PSScriptRoot ).FullName
1412 if ($RequiredResourceAccess -eq ' CIPPDefaults' ) {
15- # $RequiredResourceAccess = (Get-Content '.\SAMManifest.json' | ConvertFrom-Json).requiredResourceAccess
1613
1714 $Permissions = Get-CippSamPermissions - NoDiff
1815 $RequiredResourceAccess = [System.Collections.Generic.List [object ]]::new()
@@ -59,33 +56,72 @@ function Add-CIPPApplicationPermission {
5956 }
6057 }
6158
59+ Write-Information " Adding application permissions to application $ApplicationId in tenant $TenantFilter "
6260
63- $ServicePrincipalList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
61+ $ServicePrincipalList = [System.Collections.Generic.List [object ]]::new()
62+ $SPList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
63+ foreach ($SP in $SPList ) { $ServicePrincipalList.Add ($SP ) }
6464 $ourSVCPrincipal = $ServicePrincipalList | Where-Object - Property AppId -EQ $ApplicationId
6565 if (! $ourSVCPrincipal ) {
6666 # Our Service Principal isn't available yet. We do a sleep and reexecute after 3 seconds.
6767 Start-Sleep - Seconds 5
68- $ServicePrincipalList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
68+ $ServicePrincipalList.Clear ()
69+ $SPList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
70+ foreach ($SP in $SPList ) { $ServicePrincipalList.Add ($SP ) }
6971 $ourSVCPrincipal = $ServicePrincipalList | Where-Object - Property AppId -EQ $ApplicationId
7072 }
7173
7274 $Results = [System.Collections.Generic.List [string ]]::new()
7375
7476 $CurrentRoles = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals/$ ( $ourSVCPrincipal.id ) /appRoleAssignments" - tenantid $TenantFilter - skipTokenCache $true - NoAuthCheck $true
7577
76- $Grants = foreach ($App in $RequiredResourceAccess ) {
78+ # Collect missing service principals and prepare bulk request
79+ $MissingServicePrincipals = [System.Collections.Generic.List [object ]]::new()
80+ $AppIdToRequestId = @ {}
81+ $requestId = 1
82+
83+ foreach ($App in $RequiredResourceAccess ) {
7784 $svcPrincipalId = $ServicePrincipalList | Where-Object - Property AppId -EQ $App.resourceAppId
7885 if (! $svcPrincipalId ) {
79- try {
80- $Body = @ {
81- appId = $App.resourceAppId
82- } | ConvertTo-Json - Compress
83- $svcPrincipalId = New-GraphPOSTRequest - uri ' https://graph.microsoft.com/beta/servicePrincipals' - tenantid $TenantFilter - body $Body - type POST
84- } catch {
85- $Results.add (" Failed to create service principal for $ ( $App.resourceAppId ) : $ ( Get-NormalizedError - message $_.Exception.Message ) " )
86- continue
86+ $Body = @ {
87+ appId = $App.resourceAppId
88+ }
89+ $MissingServicePrincipals.Add (@ {
90+ id = $requestId.ToString ()
91+ method = ' POST'
92+ url = ' /servicePrincipals'
93+ headers = @ {
94+ ' Content-Type' = ' application/json'
95+ }
96+ body = $Body
97+ })
98+ $AppIdToRequestId [$App.resourceAppId ] = $requestId.ToString ()
99+ $requestId ++
100+ }
101+ }
102+
103+ # Create missing service principals in bulk
104+ if ($MissingServicePrincipals.Count -gt 0 ) {
105+ try {
106+ $BulkResults = New-GraphBulkRequest - Requests $MissingServicePrincipals - tenantid $TenantFilter - NoAuthCheck $true
107+ foreach ($Result in $BulkResults ) {
108+ if ($Result.status -eq 201 ) {
109+ $ServicePrincipalList.Add ($Result.body )
110+ } else {
111+ $AppId = ($MissingServicePrincipals | Where-Object { $_.id -eq $Result.id }).body.appId
112+ $Results.add (" Failed to create service principal for $ ( $AppId ) : $ ( $Result.body.error.message ) " )
113+ }
87114 }
115+ } catch {
116+ $Results.add (" Failed to create service principals in bulk: $ ( Get-NormalizedError - message $_.Exception.Message ) " )
88117 }
118+ }
119+
120+ # Build grants list
121+ $Grants = foreach ($App in $RequiredResourceAccess ) {
122+ $svcPrincipalId = $ServicePrincipalList | Where-Object - Property AppId -EQ $App.resourceAppId
123+ if (! $svcPrincipalId ) { continue }
124+
89125 foreach ($SingleResource in $App.ResourceAccess | Where-Object - Property Type -EQ ' Role' ) {
90126 if ($SingleResource.id -in $CurrentRoles.appRoleId ) { continue }
91127 [pscustomobject ]@ {
@@ -95,14 +131,37 @@ function Add-CIPPApplicationPermission {
95131 }
96132 }
97133 }
134+
135+ # Apply grants in bulk
98136 $counter = 0
99- foreach ($Grant in $Grants ) {
137+ if ($Grants.Count -gt 0 ) {
138+ $GrantRequests = [System.Collections.Generic.List [object ]]::new()
139+ $requestId = 1
140+ foreach ($Grant in $Grants ) {
141+ $GrantRequests.Add (@ {
142+ id = $requestId.ToString ()
143+ method = ' POST'
144+ url = " /servicePrincipals/$ ( $ourSVCPrincipal.id ) /appRoleAssignedTo"
145+ headers = @ {
146+ ' Content-Type' = ' application/json'
147+ }
148+ body = $Grant
149+ })
150+ $requestId ++
151+ }
152+
100153 try {
101- $SettingsRequest = New-GraphPOSTRequest - body (ConvertTo-Json - InputObject $Grant - Depth 5 ) - uri " https://graph.microsoft.com/beta/servicePrincipals/$ ( $ourSVCPrincipal.id ) /appRoleAssignedTo" - tenantid $TenantFilter - type POST - NoAuthCheck $true
102- $counter ++
154+ $BulkResults = New-GraphBulkRequest - Requests $GrantRequests - tenantid $TenantFilter - NoAuthCheck $true
155+ foreach ($Result in $BulkResults ) {
156+ if ($Result.status -eq 201 ) {
157+ $counter ++
158+ } else {
159+ $GrantRequest = $GrantRequests | Where-Object { $_.id -eq $Result.id }
160+ $Results.add (" Failed to grant $ ( $GrantRequest.body.appRoleId ) to $ ( $GrantRequest.body.resourceId ) : $ ( $Result.body.error.message ) " )
161+ }
162+ }
103163 } catch {
104- $ErrorMessage = Get-NormalizedError - Message $_.Exception.Message
105- $Results.add (" Failed to grant $ ( $Grant.appRoleId ) to $ ( $Grant.resourceId ) : $ErrorMessage " )
164+ $Results.add (" Failed to grant permissions in bulk: $ ( Get-NormalizedError - message $_.Exception.Message ) " )
106165 }
107166 }
108167 " Added $counter Application permissions to $ ( $ourSVCPrincipal.displayName ) "
0 commit comments