@@ -7,13 +7,11 @@ 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
14+ Set-Location (Get-Item $PSScriptRoot ).FullName
1715 $Permissions = Get-CippSamPermissions - NoDiff
1816 $RequiredResourceAccess = [System.Collections.Generic.List [object ]]::new()
1917
@@ -59,33 +57,72 @@ function Add-CIPPApplicationPermission {
5957 }
6058 }
6159
60+ Write-Information " Adding application permissions to application $ApplicationId in tenant $TenantFilter "
6261
63- $ServicePrincipalList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
62+ $ServicePrincipalList = [System.Collections.Generic.List [object ]]::new()
63+ $SPList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
64+ foreach ($SP in $SPList ) { $ServicePrincipalList.Add ($SP ) }
6465 $ourSVCPrincipal = $ServicePrincipalList | Where-Object - Property AppId -EQ $ApplicationId
6566 if (! $ourSVCPrincipal ) {
6667 # Our Service Principal isn't available yet. We do a sleep and reexecute after 3 seconds.
6768 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
69+ $ServicePrincipalList.Clear ()
70+ $SPList = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals?`$ select=AppId,id,displayName&`$ top=999" - skipTokenCache $true - tenantid $TenantFilter - NoAuthCheck $true
71+ foreach ($SP in $SPList ) { $ServicePrincipalList.Add ($SP ) }
6972 $ourSVCPrincipal = $ServicePrincipalList | Where-Object - Property AppId -EQ $ApplicationId
7073 }
7174
7275 $Results = [System.Collections.Generic.List [string ]]::new()
7376
7477 $CurrentRoles = New-GraphGETRequest - uri " https://graph.microsoft.com/beta/servicePrincipals/$ ( $ourSVCPrincipal.id ) /appRoleAssignments" - tenantid $TenantFilter - skipTokenCache $true - NoAuthCheck $true
7578
76- $Grants = foreach ($App in $RequiredResourceAccess ) {
79+ # Collect missing service principals and prepare bulk request
80+ $MissingServicePrincipals = [System.Collections.Generic.List [object ]]::new()
81+ $AppIdToRequestId = @ {}
82+ $requestId = 1
83+
84+ foreach ($App in $RequiredResourceAccess ) {
7785 $svcPrincipalId = $ServicePrincipalList | Where-Object - Property AppId -EQ $App.resourceAppId
7886 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
87+ $Body = @ {
88+ appId = $App.resourceAppId
89+ }
90+ $MissingServicePrincipals.Add (@ {
91+ id = $requestId.ToString ()
92+ method = ' POST'
93+ url = ' /servicePrincipals'
94+ headers = @ {
95+ ' Content-Type' = ' application/json'
96+ }
97+ body = $Body
98+ })
99+ $AppIdToRequestId [$App.resourceAppId ] = $requestId.ToString ()
100+ $requestId ++
101+ }
102+ }
103+
104+ # Create missing service principals in bulk
105+ if ($MissingServicePrincipals.Count -gt 0 ) {
106+ try {
107+ $BulkResults = New-GraphBulkRequest - Requests $MissingServicePrincipals - tenantid $TenantFilter - NoAuthCheck $true
108+ foreach ($Result in $BulkResults ) {
109+ if ($Result.status -eq 201 ) {
110+ $ServicePrincipalList.Add ($Result.body )
111+ } else {
112+ $AppId = ($MissingServicePrincipals | Where-Object { $_.id -eq $Result.id }).body.appId
113+ $Results.add (" Failed to create service principal for $ ( $AppId ) : $ ( $Result.body.error.message ) " )
114+ }
87115 }
116+ } catch {
117+ $Results.add (" Failed to create service principals in bulk: $ ( Get-NormalizedError - message $_.Exception.Message ) " )
88118 }
119+ }
120+
121+ # Build grants list
122+ $Grants = foreach ($App in $RequiredResourceAccess ) {
123+ $svcPrincipalId = $ServicePrincipalList | Where-Object - Property AppId -EQ $App.resourceAppId
124+ if (! $svcPrincipalId ) { continue }
125+
89126 foreach ($SingleResource in $App.ResourceAccess | Where-Object - Property Type -EQ ' Role' ) {
90127 if ($SingleResource.id -in $CurrentRoles.appRoleId ) { continue }
91128 [pscustomobject ]@ {
@@ -95,14 +132,37 @@ function Add-CIPPApplicationPermission {
95132 }
96133 }
97134 }
135+
136+ # Apply grants in bulk
98137 $counter = 0
99- foreach ($Grant in $Grants ) {
138+ if ($Grants.Count -gt 0 ) {
139+ $GrantRequests = [System.Collections.Generic.List [object ]]::new()
140+ $requestId = 1
141+ foreach ($Grant in $Grants ) {
142+ $GrantRequests.Add (@ {
143+ id = $requestId.ToString ()
144+ method = ' POST'
145+ url = " /servicePrincipals/$ ( $ourSVCPrincipal.id ) /appRoleAssignedTo"
146+ headers = @ {
147+ ' Content-Type' = ' application/json'
148+ }
149+ body = $Grant
150+ })
151+ $requestId ++
152+ }
153+
100154 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 ++
155+ $BulkResults = New-GraphBulkRequest - Requests $GrantRequests - tenantid $TenantFilter - NoAuthCheck $true
156+ foreach ($Result in $BulkResults ) {
157+ if ($Result.status -eq 201 ) {
158+ $counter ++
159+ } else {
160+ $GrantRequest = $GrantRequests | Where-Object { $_.id -eq $Result.id }
161+ $Results.add (" Failed to grant $ ( $GrantRequest.body.appRoleId ) to $ ( $GrantRequest.body.resourceId ) : $ ( $Result.body.error.message ) " )
162+ }
163+ }
103164 } catch {
104- $ErrorMessage = Get-NormalizedError - Message $_.Exception.Message
105- $Results.add (" Failed to grant $ ( $Grant.appRoleId ) to $ ( $Grant.resourceId ) : $ErrorMessage " )
165+ $Results.add (" Failed to grant permissions in bulk: $ ( Get-NormalizedError - message $_.Exception.Message ) " )
106166 }
107167 }
108168 " Added $counter Application permissions to $ ( $ourSVCPrincipal.displayName ) "
0 commit comments