Skip to content

Commit 1db85d2

Browse files
CalCachedFolderCount - faster processing by killing at least 1 request.
1 parent 36ab59b commit 1db85d2

1 file changed

Lines changed: 67 additions & 20 deletions

File tree

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Mailbox Permissions/Push-GetCalendarPermissionsBatch.ps1

Lines changed: 67 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ function Push-GetCalendarPermissionsBatch {
44
Process a batch of calendar permission queries
55
66
.DESCRIPTION
7-
Queries calendar permissions for a batch of mailboxes
7+
Queries calendar permissions for a batch of mailboxes.
8+
Uses a folder name cache to avoid the expensive Get-MailboxFolderStatistics call
9+
on subsequent runs. First run discovers and caches the locale-specific calendar
10+
folder name; all future runs skip that call entirely (50% fewer Exchange requests).
811
912
.FUNCTIONALITY
1013
Entrypoint
@@ -19,39 +22,83 @@ function Push-GetCalendarPermissionsBatch {
1922
try {
2023
Write-Information "Processing calendar permissions batch $BatchNumber of $TotalBatches for tenant $TenantFilter with $($Mailboxes.Count) mailboxes"
2124

25+
# Load cached calendar folder names for this tenant
26+
$FolderCacheTable = Get-CippTable -tablename 'CalendarFolderCache'
27+
$CachedFolders = @{}
28+
try {
29+
30+
$CacheEntries = Get-CIPPAzDataTableEntity @FolderCacheTable -Filter "PartitionKey eq '$TenantFilter'"
31+
foreach ($Entry in $CacheEntries) {
32+
$CachedFolders[$Entry.RowKey] = $Entry.FolderName
33+
}
34+
Write-Host "CAL Cached Folders count is $($CachedFolders.count)"
35+
} catch {
36+
Write-Information "Could not load folder name cache for $TenantFilter, will discover all folder names"
37+
}
38+
39+
$CacheHits = 0
40+
$CacheMisses = 0
41+
$NewCacheEntries = [System.Collections.Generic.List[hashtable]]::new()
2242
$AllCalendarPermissions = [System.Collections.Generic.List[object]]::new()
2343

2444
foreach ($MailboxUPN in $Mailboxes) {
2545
try {
26-
# Step 1: Get the calendar folder name (locale-specific)
27-
$GetCalParam = @{Identity = $MailboxUPN; FolderScope = 'Calendar' }
28-
$CalendarFolder = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxFolderStatistics' -anchor $MailboxUPN -cmdParams $GetCalParam | Select-Object -First 1
29-
30-
if ($CalendarFolder -and $CalendarFolder.name) {
31-
# Step 2: Get calendar permissions using the folder name
32-
$CalParam = @{Identity = "$($MailboxUPN):\$($CalendarFolder.name)" }
33-
$CalendarPermissions = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxFolderPermission' -anchor $MailboxUPN -cmdParams $CalParam -UseSystemMailbox $true
34-
35-
# Normalize the results
36-
foreach ($Perm in $CalendarPermissions) {
37-
$AllCalendarPermissions.Add([PSCustomObject]@{
38-
id = [guid]::NewGuid().ToString()
39-
Identity = $Perm.Identity
40-
User = $Perm.User
41-
AccessRights = $Perm.AccessRights
42-
FolderName = $Perm.FolderName
46+
# Check cache for folder name
47+
$FolderName = $CachedFolders[$MailboxUPN]
48+
49+
if (-not $FolderName) {
50+
# Cache miss — discover the locale-specific calendar folder name
51+
$CacheMisses++
52+
$GetCalParam = @{Identity = $MailboxUPN; FolderScope = 'Calendar' }
53+
$CalendarFolder = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxFolderStatistics' -anchor $MailboxUPN -cmdParams $GetCalParam | Select-Object -First 1
54+
55+
if ($CalendarFolder -and $CalendarFolder.name) {
56+
$FolderName = $CalendarFolder.name
57+
# Queue for cache write
58+
$NewCacheEntries.Add(@{
59+
PartitionKey = $TenantFilter
60+
RowKey = $MailboxUPN
61+
FolderName = $FolderName
4362
})
63+
} else {
64+
Write-Information "No calendar folder found for mailbox $MailboxUPN"
65+
continue
4466
}
4567
} else {
46-
Write-Information "No calendar folder found for mailbox $MailboxUPN"
68+
$CacheHits++
69+
}
70+
71+
# Get calendar permissions using the folder name
72+
$CalParam = @{Identity = "$($MailboxUPN):\$($FolderName)" }
73+
$CalendarPermissions = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-MailboxFolderPermission' -anchor $MailboxUPN -cmdParams $CalParam -UseSystemMailbox $true
74+
75+
# Normalize the results
76+
foreach ($Perm in $CalendarPermissions) {
77+
$AllCalendarPermissions.Add([PSCustomObject]@{
78+
id = [guid]::NewGuid().ToString()
79+
Identity = $Perm.Identity
80+
User = $Perm.User
81+
AccessRights = $Perm.AccessRights
82+
FolderName = $Perm.FolderName
83+
})
4784
}
4885
} catch {
4986
Write-Information "Failed to get calendar permissions for $MailboxUPN : $($_.Exception.Message)"
5087
# Continue processing other mailboxes
5188
}
5289
}
5390

54-
Write-Information "Completed calendar permissions batch $BatchNumber of $TotalBatches - processed $($Mailboxes.Count) mailboxes: $($AllCalendarPermissions.Count) calendar permissions"
91+
# Persist newly discovered folder names to cache
92+
if ($NewCacheEntries.Count -gt 0) {
93+
try {
94+
Add-CIPPAzDataTableEntity @FolderCacheTable -Entity $NewCacheEntries -Force
95+
Write-Information "Cached $($NewCacheEntries.Count) new calendar folder names for $TenantFilter"
96+
} catch {
97+
Write-Information "Failed to write folder name cache for $TenantFilter : $($_.Exception.Message)"
98+
}
99+
}
100+
101+
Write-Information "Completed calendar permissions batch $BatchNumber of $TotalBatches - processed $($Mailboxes.Count) mailboxes: $($AllCalendarPermissions.Count) permissions (cache hits: $CacheHits, misses: $CacheMisses)"
55102

56103
# Return results grouped by command type for consistency with mailbox permissions
57104
return @{

0 commit comments

Comments
 (0)