@@ -21,59 +21,75 @@ function Test-CIPPAccessUserRole {
2121 )
2222 $Roles = @ ()
2323
24- try {
25- $Table = Get-CippTable - TableName cacheAccessUserRoles
26- $Filter = " PartitionKey eq 'AccessUser' and RowKey eq '$ ( $User.userDetails ) ' and Timestamp ge datetime'$ ( (Get-Date ).AddMinutes(-15 ).ToUniversalTime().ToString(' yyyy-MM-ddTHH:mm:ss.fffZ' )) '"
27- $UserRole = Get-CIPPAzDataTableEntity @Table - Filter $Filter
28- } catch {
29- Write-Information " Could not access cached user roles table. $ ( $_.Exception.Message ) "
30- $UserRole = $null
31- }
32- if ($UserRole ) {
33- Write-Information " Found cached user role for $ ( $User.userDetails ) "
34- $Roles = $UserRole.Role | ConvertFrom-Json
24+ # Check AsyncLocal cache first (per-request cache)
25+ if ($script :CippUserRolesStorage -and $script :CippUserRolesStorage.Value -and $script :CippUserRolesStorage.Value.ContainsKey ($User.userDetails )) {
26+ $Roles = $script :CippUserRolesStorage.Value [$User.userDetails ]
3527 } else {
28+ # Check table storage cache (persistent cache)
3629 try {
37- $uri = " https://graph.microsoft.com/beta/users/$ ( $User.userDetails ) /transitiveMemberOf"
38- $Memberships = New-GraphGetRequest - uri $uri - NoAuthCheck $true - AsApp $true | Where-Object { $_ .' @odata.type' -eq ' #microsoft.graph.group' }
39- if ($Memberships ) {
40- Write-Information " Found group memberships for $ ( $User.userDetails ) "
41- } else {
42- Write-Information " No group memberships found for $ ( $User.userDetails ) "
43- }
30+ $Table = Get-CippTable - TableName cacheAccessUserRoles
31+ $Filter = " PartitionKey eq 'AccessUser' and RowKey eq '$ ( $User.userDetails ) ' and Timestamp ge datetime'$ ( (Get-Date ).AddMinutes(-15 ).ToUniversalTime().ToString(' yyyy-MM-ddTHH:mm:ss.fffZ' )) '"
32+ $UserRole = Get-CIPPAzDataTableEntity @Table - Filter $Filter
4433 } catch {
45- Write-Information " Could not get user roles for $ ( $User .userDetails ) . $ ( $_.Exception.Message ) "
46- return $User
34+ Write-Information " Could not access cached user roles table . $ ( $_.Exception.Message ) "
35+ $UserRole = $null
4736 }
37+ if ($UserRole ) {
38+ Write-Information " Found cached user role for $ ( $User.userDetails ) "
39+ $Roles = $UserRole.Role | ConvertFrom-Json
40+
41+ # Store in AsyncLocal cache for this request
42+ if ($script :CippUserRolesStorage -and $script :CippUserRolesStorage.Value ) {
43+ $script :CippUserRolesStorage.Value [$User.userDetails ] = $Roles
44+ }
45+ } else {
46+ try {
47+ $uri = " https://graph.microsoft.com/beta/users/$ ( $User.userDetails ) /transitiveMemberOf"
48+ $Memberships = New-GraphGetRequest - uri $uri - NoAuthCheck $true - AsApp $true | Where-Object { $_ .' @odata.type' -eq ' #microsoft.graph.group' }
49+ if ($Memberships ) {
50+ Write-Information " Found group memberships for $ ( $User.userDetails ) "
51+ } else {
52+ Write-Information " No group memberships found for $ ( $User.userDetails ) "
53+ }
54+ } catch {
55+ Write-Information " Could not get user roles for $ ( $User.userDetails ) . $ ( $_.Exception.Message ) "
56+ return $User
57+ }
4858
49- $AccessGroupsTable = Get-CippTable - TableName AccessRoleGroups
50- $AccessGroups = Get-CIPPAzDataTableEntity @AccessGroupsTable - Filter " PartitionKey eq 'AccessRoleGroups'"
51- $CustomRolesTable = Get-CippTable - TableName CustomRoles
52- $CustomRoles = Get-CIPPAzDataTableEntity @CustomRolesTable - Filter " PartitionKey eq 'CustomRoles'"
53- $BaseRoles = @ (' superadmin' , ' admin' , ' editor' , ' readonly' )
59+ $AccessGroupsTable = Get-CippTable - TableName AccessRoleGroups
60+ $AccessGroups = Get-CIPPAzDataTableEntity @AccessGroupsTable - Filter " PartitionKey eq 'AccessRoleGroups'"
61+ $CustomRolesTable = Get-CippTable - TableName CustomRoles
62+ $CustomRoles = Get-CIPPAzDataTableEntity @CustomRolesTable - Filter " PartitionKey eq 'CustomRoles'"
63+ $BaseRoles = @ (' superadmin' , ' admin' , ' editor' , ' readonly' )
5464
55- $Roles = foreach ($AccessGroup in $AccessGroups ) {
56- if ($Memberships.id -contains $AccessGroup.GroupId -and ($CustomRoles.RowKey -contains $AccessGroup.RowKey -or $BaseRoles -contains $AccessGroup.RowKey )) {
57- $AccessGroup.RowKey
65+ $Roles = foreach ($AccessGroup in $AccessGroups ) {
66+ if ($Memberships.id -contains $AccessGroup.GroupId -and ($CustomRoles.RowKey -contains $AccessGroup.RowKey -or $BaseRoles -contains $AccessGroup.RowKey )) {
67+ $AccessGroup.RowKey
68+ }
5869 }
59- }
6070
61- $Roles = @ ($Roles ) + @ ($User.userRoles )
71+ $Roles = @ ($Roles ) + @ ($User.userRoles )
6272
63- if ($Roles ) {
64- Write-Information " Roles determined for $ ( $User.userDetails ) : $ ( $Roles -join ' , ' ) "
65- }
73+ if ($Roles ) {
74+ Write-Information " Roles determined for $ ( $User.userDetails ) : $ ( $Roles -join ' , ' ) "
75+ }
6676
67- if (($Roles | Measure-Object ).Count -gt 2 ) {
68- try {
69- $UserRole = [PSCustomObject ]@ {
70- PartitionKey = ' AccessUser'
71- RowKey = [string ]$User.userDetails
72- Role = [string ](ConvertTo-Json - Compress - InputObject $Roles )
77+ if (($Roles | Measure-Object ).Count -gt 2 ) {
78+ try {
79+ $UserRole = [PSCustomObject ]@ {
80+ PartitionKey = ' AccessUser'
81+ RowKey = [string ]$User.userDetails
82+ Role = [string ](ConvertTo-Json - Compress - InputObject $Roles )
83+ }
84+ Add-CIPPAzDataTableEntity @Table - Entity $UserRole - Force
85+ } catch {
86+ Write-Information " Could not cache user roles for $ ( $User.userDetails ) . $ ( $_.Exception.Message ) "
7387 }
74- Add-CIPPAzDataTableEntity @Table - Entity $UserRole - Force
75- } catch {
76- Write-Information " Could not cache user roles for $ ( $User.userDetails ) . $ ( $_.Exception.Message ) "
88+ }
89+
90+ # Store in AsyncLocal cache for this request
91+ if ($script :CippUserRolesStorage -and $script :CippUserRolesStorage.Value ) {
92+ $script :CippUserRolesStorage.Value [$User.userDetails ] = $Roles
7793 }
7894 }
7995 }
0 commit comments