1+ function Invoke-ExecApplication {
2+ <#
3+ . FUNCTIONALITY
4+ Entrypoint
5+ . ROLE
6+ Tenant.Application.ReadWrite
7+ #>
8+ [CmdletBinding ()]
9+ param ($Request , $TriggerMetadata )
10+
11+ $APIName = $Request.Params.CIPPEndpoint
12+ $Headers = $Request.Headers
13+ Write-LogMessage - headers $Headers - API $APIName - message ' Accessed this API' - Sev ' Debug'
14+
15+ $ValidTypes = @ (' applications' , ' servicePrincipals' )
16+ $ValidActions = @ (' Update' , ' Upsert' , ' Delete' , ' RemoveKey' , ' RemovePassword' )
17+
18+ $Id = $Request.Query.Id ?? $Request.Body.Id
19+ $Type = $Request.Query.Type ?? $Request.Body.Type
20+ if (-not $Id ) {
21+ $AppId = $Request.Query.AppId ?? $Request.Body.AppId
22+ if (-not $AppId ) {
23+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
24+ StatusCode = [HttpStatusCode ]::BadRequest
25+ Body = " Required parameter 'Id' or 'AppId' is missing"
26+ })
27+ return
28+ }
29+ $IdPath = " (appId='$AppId ')"
30+ } else {
31+ $IdPath = " /$Id "
32+ }
33+ if ($Type -and $ValidTypes -notcontains $Type ) {
34+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
35+ StatusCode = [HttpStatusCode ]::BadRequest
36+ Body = " Invalid Type specified. Valid types are: $ ( $ValidTypes -join ' , ' ) "
37+ })
38+ return
39+ }
40+
41+ $Uri = " https://graph.microsoft.com/beta/$ ( $Type ) $ ( $IdPath ) "
42+ $Action = $Request.Query.Action ?? $Request.Body.Action
43+
44+ if ($ValidActions -notcontains $Action ) {
45+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
46+ StatusCode = [HttpStatusCode ]::BadRequest
47+ Body = " Invalid Action specified. Valid actions are: $ ( $ValidActions -join ' , ' ) "
48+ })
49+ return
50+ }
51+
52+ $PostParams = @ {
53+ Uri = $Uri
54+ }
55+
56+ if ($Action -eq ' Delete' ) {
57+ $PostParams.Type = ' DELETE'
58+ }
59+ if ($Action -eq ' Update' -or $Action -eq ' Upsert' ) {
60+ $PostParams.Type = ' PATCH'
61+ }
62+
63+ if ($Action -eq ' Upsert' ) {
64+ $PostParams.AddedHeaders = @ {
65+ ' Prefer' = ' create-if-missing'
66+ }
67+ }
68+
69+ if ($Request.Body ) {
70+ $PostParams.Body = $Request.Body.Payload | ConvertTo-Json - Compress
71+ }
72+
73+ $TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter
74+
75+ try {
76+ if ($Action -eq ' RemoveKey' -or $Action -eq ' RemovePassword' ) {
77+ # Handle credential removal by patching the object
78+ $KeyIds = $Request.Body.KeyIds.value ?? $Request.Body.KeyIds
79+ if (-not $KeyIds -or $KeyIds.Count -eq 0 ) {
80+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
81+ StatusCode = [HttpStatusCode ]::BadRequest
82+ Body = " KeyIds parameter is required for $Action action"
83+ })
84+ return
85+ }
86+
87+ # Get the current application/service principal
88+ $CurrentObject = New-GraphGetRequest - Uri $Uri - tenantid $TenantFilter - AsApp $true
89+
90+ if ($Action -eq ' RemoveKey' ) {
91+ # Filter out the key credentials to remove
92+ $UpdatedKeyCredentials = $CurrentObject.keyCredentials | Where-Object { $_.keyId -notin $KeyIds }
93+ $PatchBody = @ {
94+ keyCredentials = @ ($UpdatedKeyCredentials )
95+ }
96+ } else {
97+ # Filter out the password credentials to remove
98+ $UpdatedPasswordCredentials = $CurrentObject.passwordCredentials | Where-Object { $_.keyId -notin $KeyIds }
99+ $PatchBody = @ {
100+ passwordCredentials = @ ($UpdatedPasswordCredentials )
101+ }
102+ }
103+
104+ # Update the object with the filtered credentials
105+ $null = New-GraphPOSTRequest - Uri $Uri - Type ' PATCH' - Body ($PatchBody | ConvertTo-Json - Depth 10 ) - tenantid $TenantFilter - AsApp $true
106+
107+ $Results = @ {
108+ resultText = " Successfully removed $ ( $KeyIds.Count ) credential(s) from $Type "
109+ state = ' success'
110+ }
111+ } else {
112+ # Handle regular actions
113+ $null = New-GraphPOSTRequest @PostParams - tenantid $TenantFilter - AsApp $true
114+ $Results = @ {
115+ resultText = " Successfully executed $Action on $Type with Id: $Id "
116+ state = ' success'
117+ }
118+ }
119+
120+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
121+ StatusCode = [HttpStatusCode ]::OK
122+ Body = @ { Results = $Results }
123+ })
124+ } catch {
125+ $Results = @ {
126+ resultText = " Failed to execute $Action on $Type with Id: $Id . Error: $ ( $_.Exception.Message ) "
127+ state = ' error'
128+ }
129+
130+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
131+ StatusCode = [HttpStatusCode ]::InternalServerError
132+ Body = @ { Results = @ ($Results ) }
133+ })
134+ }
135+ }
0 commit comments