@@ -10,51 +10,126 @@ function Invoke-ExecJITAdmin {
10
10
[CmdletBinding ()]
11
11
param ($Request , $TriggerMetadata )
12
12
13
- $APIName = ' ExecJITAdmin '
13
+ $APIName = $Request .Params.CIPPEndpoint
14
14
$User = $Request.Headers
15
- $TenantFilter = $Request.body.TenantFilter .value ? $Request.body.TenantFilter .value : $Request.body.TenantFilter
16
- Write-LogMessage - Headers $User - API $APINAME - message ' Accessed this API' - Sev ' Debug'
15
+ $TenantFilter = $Request.Body.tenantFilter .value ? $Request.Body.tenantFilter .value : $Request.Body.tenantFilter
16
+ Write-LogMessage - Headers $User - API $APIName - message ' Accessed this API' - Sev ' Debug'
17
17
18
18
if ($Request.Query.Action -eq ' List' ) {
19
19
$Schema = Get-CIPPSchemaExtensions | Where-Object { $_.id -match ' _cippUser' } | Select-Object - First 1
20
- $Query = @ {
21
- TenantFilter = $Request.Query.TenantFilter
22
- Endpoint = ' users'
23
- Parameters = @ {
24
- ' $count' = ' true'
25
- ' $select' = " id,accountEnabled,displayName,userPrincipalName,$ ( $Schema.id ) "
26
- ' $filter' = " $ ( $Schema.id ) /jitAdminEnabled eq true or $ ( $Schema.id ) /jitAdminEnabled eq false"
20
+ if ($TenantFilter -ne ' AllTenants' ) {
21
+ $Query = @ {
22
+ TenantFilter = $Request.Query.TenantFilter
23
+ Endpoint = ' users'
24
+ Parameters = @ {
25
+ ' $count' = ' true'
26
+ ' $select' = " id,accountEnabled,displayName,userPrincipalName,$ ( $Schema.id ) "
27
+ ' $filter' = " $ ( $Schema.id ) /jitAdminEnabled eq true or $ ( $Schema.id ) /jitAdminEnabled eq false"
28
+ }
27
29
}
28
- }
29
- $Users = Get-GraphRequestList @Query | Where-Object { $_.id }
30
- $BulkRequests = $Users | ForEach-Object { @ (
31
- @ {
32
- id = $_.id
33
- method = ' GET'
34
- url = " users/$ ( $_.id ) /memberOf/microsoft.graph.directoryRole/?`$ select=id,displayName"
30
+ $Users = Get-GraphRequestList @Query | Where-Object { $_.id }
31
+ $BulkRequests = $Users | ForEach-Object { @ (
32
+ @ {
33
+ id = $_.id
34
+ method = ' GET'
35
+ url = " users/$ ( $_.id ) /memberOf/microsoft.graph.directoryRole/?`$ select=id,displayName"
36
+ }
37
+ )
38
+ }
39
+ # Use $TenantFilter consistently, which is derived from Body or Query params at line 15
40
+ $RoleResults = New-GraphBulkRequest - tenantid $Request.Query.TenantFilter - Requests @ ($BulkRequests )
41
+ # Write-Information ($RoleResults | ConvertTo-Json -Depth 10 )
42
+ $Results = $Users | ForEach-Object {
43
+ $MemberOf = ($RoleResults | Where-Object - Property id -EQ $_.id ).body.value | Select-Object displayName, id
44
+ [PSCustomObject ]@ {
45
+ id = $_.id
46
+ displayName = $_.displayName
47
+ userPrincipalName = $_.userPrincipalName
48
+ accountEnabled = $_.accountEnabled
49
+ jitAdminEnabled = $_ .($Schema.id ).jitAdminEnabled
50
+ jitAdminExpiration = $_ .($Schema.id ).jitAdminExpiration
51
+ memberOf = $MemberOf
35
52
}
36
- )
37
- }
38
- $RoleResults = New-GraphBulkRequest - tenantid $Request.Query.TenantFilter - Requests @ ($BulkRequests )
39
- # Write-Information ($RoleResults | ConvertTo-Json -Depth 10 )
40
- $Results = $Users | ForEach-Object {
41
- $MemberOf = ($RoleResults | Where-Object - Property id -EQ $_.id ).body.value | Select-Object displayName, id
42
- [PSCustomObject ]@ {
43
- id = $_.id
44
- displayName = $_.displayName
45
- userPrincipalName = $_.userPrincipalName
46
- accountEnabled = $_.accountEnabled
47
- jitAdminEnabled = $_ .($Schema.id ).jitAdminEnabled
48
- jitAdminExpiration = $_ .($Schema.id ).jitAdminExpiration
49
- memberOf = $MemberOf
50
53
}
51
- }
52
54
53
- # Write-Information ($Results | ConvertTo-Json -Depth 10)
54
- $Body = @ {
55
- Results = @ ($Results )
56
- Metadata = @ {
57
- Parameters = $Query.Parameters
55
+ # Write-Information ($Results | ConvertTo-Json -Depth 10)
56
+ $Body = @ {
57
+ Results = @ ($Results )
58
+ Metadata = @ {
59
+ Parameters = $Query.Parameters
60
+ }
61
+ }
62
+ } else {
63
+ # AllTenants logic
64
+ $Results = [System.Collections.Generic.List [object ]]::new()
65
+ $Metadata = @ {}
66
+ # Assumed table name for JIT Admin cache. User might need to adjust.
67
+ $Table = Get-CIPPTable - TableName CacheJITAdmin
68
+ $PartitionKey = ' JITAdminUsers' # Assumed partition key
69
+
70
+ # Filter for recent data, e.g., last 60 minutes. Orchestrator populates this.
71
+ $Filter = " PartitionKey eq '$PartitionKey '"
72
+ $Rows = Get-CIPPAzDataTableEntity @Table - filter $Filter | Where-Object - Property Timestamp -GT (Get-Date ).AddMinutes(-1 )
73
+
74
+ $QueueReference = ' {0}-{1}' -f $Request.Query.TenantFilter , $PartitionKey # $TenantFilter is 'AllTenants'
75
+ $RunningQueue = Invoke-ListCippQueue | Where-Object { $_.Reference -eq $QueueReference -and $_.Status -notmatch ' Completed' -and $_.Status -notmatch ' Failed' }
76
+
77
+ if ($RunningQueue ) {
78
+ $Metadata = [PSCustomObject ]@ {
79
+ QueueMessage = ' Still loading JIT Admin data for all tenants. Please check back in a few more minutes.'
80
+ }
81
+ $Results.Add ([PSCustomObject ]@ { Waiting = $true })
82
+ } elseif (! $dRows -and ! $RunningQueue ) {
83
+ $TenantList = Get-Tenants - IncludeErrors
84
+ $QueueLink = if ($Request.RequestUri ) { $Request.RequestUri.ToString () -replace $Request.Query.Action , ' List' } else { ' /identity/administration/users/jit-admin?Action=List&TenantFilter=AllTenants' } # Fallback link
85
+ $Queue = New-CippQueueEntry - Name ' JIT Admin List - All Tenants' - Link $QueueLink - Reference $QueueReference - TotalTasks ($TenantList | Measure-Object ).Count
86
+
87
+ $Metadata = [PSCustomObject ]@ {
88
+ QueueMessage = ' Loading JIT Admin data for all tenants. Please check back in a few minutes.'
89
+ }
90
+ $InputObject = [PSCustomObject ]@ {
91
+ OrchestratorName = ' JITAdminListAllTenantsOrchestrator' # Assumed orchestrator name
92
+ QueueFunction = @ {
93
+ FunctionName = ' GetTenants' # Generic entry, durable function handles per-tenant logic
94
+ QueueId = $Queue.RowKey
95
+ TenantParams = @ {
96
+ IncludeErrors = $true
97
+ }
98
+ DurableName = ' ExecJITAdminListAllTenants'
99
+ }
100
+ SkipLog = $true
101
+ }
102
+ Start-NewOrchestration - FunctionName ' CIPPOrchestrator' - InputObject ($InputObject | ConvertTo-Json - Depth 5 - Compress)
103
+ $Results.Add ([PSCustomObject ]@ { Waiting = $true })
104
+ } else {
105
+ # $dRows exist
106
+ foreach ($row in $Rows ) {
107
+ # Assuming $row.JITUserObject contains the serialized PSCustomObject for the user's JIT details
108
+ # And $row.TenantId (or $row.TenantDisplayName) contains the tenant identifier
109
+ try {
110
+ $UserObject = $row.JITUserObject | ConvertFrom-Json
111
+ $Results.Add (
112
+ [PSCustomObject ]@ {
113
+ Tenant = $row.TenantId # Or TenantDisplayName, ensure orchestrator stores this
114
+ id = $UserObject.id
115
+ displayName = $UserObject.displayName
116
+ userPrincipalName = $UserObject.userPrincipalName
117
+ accountEnabled = $UserObject.accountEnabled
118
+ jitAdminEnabled = $UserObject.jitAdminEnabled
119
+ jitAdminExpiration = $UserObject.jitAdminExpiration
120
+ memberOf = $UserObject.memberOf # This should be an array of role objects
121
+ }
122
+ )
123
+ } catch {
124
+ Write-LogMessage - Headers $User - API $APIName - message " Failed to process cached JIT admin row for Tenant $ ( $row.TenantId ) , RowKey $ ( $row.RowKey ) . Error: $ ( $_.Exception.Message ) " - Sev ' Warning'
125
+ # Optionally add a placeholder or skip if critical
126
+ }
127
+ }
128
+ $Metadata = @ { Info = ' Displaying cached JIT Admin data for all tenants.' }
129
+ }
130
+ $Body = @ {
131
+ Results = @ ($Results )
132
+ Metadata = $Metadata
58
133
}
59
134
}
60
135
} else {
0 commit comments