Skip to content

Commit 8aac516

Browse files
authored
Merge pull request #749 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 179223c + c1d27e1 commit 8aac516

15 files changed

+499
-152
lines changed

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/CIPPDBCache/Push-ExecCIPPDBCache.ps1

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ function Push-ExecCIPPDBCache {
1515
$Name = $Item.Name
1616
$TenantFilter = $Item.TenantFilter
1717
$QueueId = $Item.QueueId
18+
$Types = $Item.Types
1819

1920
try {
2021
Write-Information "Collecting $Name for tenant $TenantFilter"
@@ -38,6 +39,13 @@ function Push-ExecCIPPDBCache {
3839
$CacheFunctionParams.QueueId = $QueueId
3940
}
4041

42+
# Add Types if provided (for Mailboxes function)
43+
if ($Types) {
44+
$CacheFunctionParams.Types = $Types
45+
}
46+
47+
Write-Information "Executing $FullFunctionName with parameters: $(($CacheFunctionParams.GetEnumerator() | ForEach-Object { "$($_.Key)=$($_.Value)" }) -join ', '))"
48+
4149
# Execute the cache function
4250
& $FullFunctionName @CacheFunctionParams
4351

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-CIPPDBCacheData.ps1

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,6 @@ function Push-CIPPDBCacheData {
9999
'ExoPresetSecurityPolicy'
100100
'ExoTenantAllowBlockList'
101101
'Mailboxes'
102-
'MailboxRules'
103102
'CASMailboxes'
104103
'MailboxUsage'
105104
'OneDriveUsage'
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
function Push-GetMailboxRulesBatch {
2+
<#
3+
.SYNOPSIS
4+
Caches mailbox rules for a batch of mailboxes
5+
6+
.PARAMETER InputObject
7+
The batch object containing TenantFilter and Mailboxes array
8+
#>
9+
[CmdletBinding()]
10+
param($Item)
11+
12+
$TenantFilter = $Item.TenantFilter
13+
$Mailboxes = $Item.Mailboxes
14+
$BatchNumber = $Item.BatchNumber
15+
$TotalBatches = $Item.TotalBatches
16+
$QueueId = $Item.QueueId
17+
18+
try {
19+
Write-Information "Processing mailbox rules batch $BatchNumber/$TotalBatches for tenant $TenantFilter with $($Mailboxes.Count) mailboxes"
20+
21+
# Build bulk request for mailbox rules
22+
$Request = $Mailboxes | ForEach-Object {
23+
@{
24+
OperationGuid = $_
25+
CmdletInput = @{
26+
CmdletName = 'Get-InboxRule'
27+
Parameters = @{
28+
Mailbox = $_
29+
}
30+
}
31+
}
32+
}
33+
34+
$Rules = New-ExoBulkRequest -tenantid $TenantFilter -cmdletArray @($Request) | Where-Object { $_.Identity }
35+
36+
Write-Information "Retrieved $($Rules.Count) rules from batch $BatchNumber/$TotalBatches"
37+
38+
# Add metadata and return for aggregation
39+
if (($Rules | Measure-Object).Count -gt 0) {
40+
$RulesWithMetadata = foreach ($Rule in $Rules) {
41+
$Rule | Add-Member -NotePropertyName 'Tenant' -NotePropertyValue $TenantFilter -Force
42+
$Rule | Add-Member -NotePropertyName 'UserPrincipalName' -NotePropertyValue $Rule.OperationGuid -Force
43+
$Rule
44+
}
45+
return , $RulesWithMetadata
46+
} else {
47+
Write-Information "No rules found in batch $BatchNumber/$TotalBatches"
48+
return , @()
49+
}
50+
51+
} catch {
52+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Failed to process mailbox rules batch $BatchNumber/$TotalBatches : $($_.Exception.Message)" -sev Error -LogData (Get-CippException -Exception $_)
53+
throw
54+
}
55+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
function Push-StoreMailboxRules {
2+
<#
3+
.SYNOPSIS
4+
Post-execution function to aggregate and store all mailbox rules
5+
6+
.DESCRIPTION
7+
Collects results from all batches and stores them in the reporting database
8+
9+
.FUNCTIONALITY
10+
Entrypoint
11+
#>
12+
[CmdletBinding()]
13+
param($Item)
14+
15+
$TenantFilter = $Item.Parameters.TenantFilter
16+
$Results = $Item.Results
17+
18+
try {
19+
Write-Information "Storing mailbox rules for tenant $TenantFilter"
20+
Write-Information "Received $($Results.Count) batch results"
21+
22+
# Aggregate all rules from batches
23+
$AllRules = [System.Collections.Generic.List[object]]::new()
24+
25+
foreach ($BatchResult in $Results) {
26+
# Activity functions may return an array
27+
$ActualResult = $BatchResult
28+
if ($BatchResult -is [array] -and $BatchResult.Count -gt 0) {
29+
Write-Information "Result is array with $($BatchResult.Count) elements"
30+
# If first element is array of rules, use it
31+
if ($BatchResult[0] -is [array]) {
32+
$ActualResult = $BatchResult[0]
33+
} else {
34+
$ActualResult = $BatchResult
35+
}
36+
}
37+
38+
if ($ActualResult) {
39+
if ($ActualResult -is [array]) {
40+
Write-Information "Adding $($ActualResult.Count) rules from batch"
41+
$AllRules.AddRange($ActualResult)
42+
} else {
43+
Write-Information 'Adding 1 rule from batch'
44+
$AllRules.Add($ActualResult)
45+
}
46+
}
47+
}
48+
49+
Write-Information "Aggregated $($AllRules.Count) total mailbox rules"
50+
51+
# Store all rules
52+
if ($AllRules.Count -gt 0) {
53+
$AllRules | Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'MailboxRules' -AddCount
54+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Cached $($AllRules.Count) mailbox rules" -sev Info
55+
} else {
56+
# Store empty result to indicate successful check with no rules
57+
@() | Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'MailboxRules' -AddCount
58+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'No mailbox rules found to cache' -sev Info
59+
}
60+
61+
return
62+
63+
} catch {
64+
$ErrorMsg = "Failed to store mailbox rules for tenant $TenantFilter : $($_.Exception.Message)"
65+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message $ErrorMsg -sev Error
66+
throw $ErrorMsg
67+
}
68+
}

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Core/Invoke-ExecCIPPDBCache.ps1

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ function Invoke-ExecCIPPDBCache {
1111
$APIName = $Request.Params.CIPPEndpoint
1212
$TenantFilter = $Request.Query.TenantFilter
1313
$Name = $Request.Query.Name
14+
$Types = $Request.Query.Types
1415

15-
Write-Information "ExecCIPPDBCache called with Name: '$Name', TenantFilter: '$TenantFilter'"
16+
Write-Information "ExecCIPPDBCache called with Name: '$Name', TenantFilter: '$TenantFilter', Types: '$Types'"
1617

1718
try {
1819
if ([string]::IsNullOrEmpty($Name)) {
@@ -30,8 +31,6 @@ function Invoke-ExecCIPPDBCache {
3031
throw "Cache function '$FunctionName' not found"
3132
}
3233

33-
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Starting CIPP DB cache for $Name" -sev Info
34-
3534
# Create queue entry for tracking
3635
$QueueName = if ($TenantFilter -eq 'AllTenants') {
3736
"$Name Cache Sync (All Tenants)"
@@ -45,13 +44,18 @@ function Invoke-ExecCIPPDBCache {
4544
$Queue = New-CippQueueEntry -Name $QueueName -TotalTasks ($TenantList | Measure-Object).Count
4645

4746
$Batch = $TenantList | ForEach-Object {
48-
[PSCustomObject]@{
47+
$BatchItem = [PSCustomObject]@{
4948
FunctionName = 'ExecCIPPDBCache'
50-
QueueName = "$Name Cache - $($_.defaultDomainName)"
5149
Name = $Name
50+
QueueName = "$Name Cache - $($_.defaultDomainName)"
5251
TenantFilter = $_.defaultDomainName
5352
QueueId = $Queue.RowKey
5453
}
54+
# Add Types parameter if provided
55+
if ($Types) {
56+
$BatchItem | Add-Member -NotePropertyName 'Types' -NotePropertyValue @($Types -split ',') -Force
57+
}
58+
$BatchItem
5559
}
5660

5761
$InputObject = [PSCustomObject]@{
@@ -60,28 +64,33 @@ function Invoke-ExecCIPPDBCache {
6064
SkipLog = $false
6165
}
6266

63-
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Starting CIPP DB cache for $Name across $($TenantList.Count) tenants" -sev Info
67+
Write-LogMessage -Headers $Request.Headers -API $APIName -tenant $TenantFilter -message "Starting CIPP DB cache for $Name across $($TenantList.Count) tenants" -sev Info
6468
} else {
6569
# Single tenant
6670
$Queue = New-CippQueueEntry -Name $QueueName -TotalTasks 1
6771

72+
$BatchItem = [PSCustomObject]@{
73+
FunctionName = 'ExecCIPPDBCache'
74+
Name = $Name
75+
QueueName = "$Name Cache - $TenantFilter"
76+
TenantFilter = $TenantFilter
77+
QueueId = $Queue.RowKey
78+
}
79+
# Add Types parameter if provided
80+
if ($Types) {
81+
$BatchItem | Add-Member -NotePropertyName 'Types' -NotePropertyValue @($Types -split ',') -Force
82+
}
83+
6884
$InputObject = [PSCustomObject]@{
69-
Batch = @([PSCustomObject]@{
70-
QueueName = "$Name Cache - $TenantFilter"
71-
FunctionName = 'ExecCIPPDBCache'
72-
Name = $Name
73-
TenantFilter = $TenantFilter
74-
QueueId = $Queue.RowKey
75-
})
85+
Batch = @($BatchItem)
7686
OrchestratorName = "CIPPDBCache_${Name}_$TenantFilter"
7787
SkipLog = $false
7888
}
89+
Write-LogMessage -Headers $Request.Headers -API $APIName -tenant $TenantFilter -message "Starting CIPP DB cache for $Name on tenant $TenantFilter" -sev Info
7990
}
8091

8192
$InstanceId = Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Compress -Depth 5)
8293

83-
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Started CIPP DB cache orchestrator for $Name with instance ID: $InstanceId" -sev Info
84-
8594
$ResultsMessage = if ($TenantFilter -eq 'AllTenants') {
8695
"Successfully started cache operation for $Name for all tenants"
8796
} else {

Modules/CIPPCore/Public/Entrypoints/Orchestrator Functions/Start-UserTasksOrchestrator.ps1

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,6 @@ function Start-UserTasksOrchestrator {
151151
# Process each tenant batch separately
152152
foreach ($ProcessedBatch in $ProcessedBatches) {
153153
$TenantName = $ProcessedBatch[0].Parameters.TenantFilter
154-
Write-Information "Processing batch for tenant: $TenantName with $($ProcessedBatch.Count) tasks..."
155-
Write-Information 'Tasks by command:'
156-
$ProcessedBatch | Group-Object -Property Command | ForEach-Object {
157-
Write-Information " - $($_.Name): $($_.Count)"
158-
}
159154

160155
# Create queue entry for each tenant batch
161156
$Queue = New-CippQueueEntry -Name "Scheduled Tasks - $TenantName"

Modules/CIPPCore/Public/Entrypoints/Timer Functions/Start-TableCleanup.ps1

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,16 @@ function Start-TableCleanup {
6565
Property = @('PartitionKey', 'RowKey', 'ETag')
6666
}
6767
}
68+
@{
69+
FunctionName = 'TableCleanupTask'
70+
Type = 'CleanupRule'
71+
TableName = 'CippStandardsReports'
72+
DataTableProps = @{
73+
Filter = "Timestamp lt datetime'$((Get-Date).AddDays(-7).ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ssZ'))'"
74+
First = 10000
75+
Property = @('PartitionKey', 'RowKey', 'ETag')
76+
}
77+
}
6878
@{
6979
FunctionName = 'TableCleanupTask'
7080
Type = 'DeleteTable'

Modules/CIPPCore/Public/Get-CIPPLicenseOverview.ps1

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,13 @@ function Get-CIPPLicenseOverview {
5656
$LicenseTable = Get-CIPPTable -TableName ExcludedLicenses
5757
$ExcludedSkuList = Get-CIPPAzDataTableEntity @LicenseTable
5858

59+
# If no excluded licenses exist, initialize them
60+
if ($ExcludedSkuList.Count -lt 1) {
61+
Write-Information 'Excluded licenses table is empty. Initializing from config file.'
62+
$null = Initialize-CIPPExcludedLicenses
63+
$ExcludedSkuList = Get-CIPPAzDataTableEntity @LicenseTable
64+
}
65+
5966
$AllLicensedUsers = @(($Results | Where-Object { $_.id -eq 'licensedUsers' }).body.value)
6067
$UsersBySku = @{}
6168
foreach ($User in $AllLicensedUsers) {
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
function Remove-CIPPDbItem {
2+
<#
3+
.SYNOPSIS
4+
Remove an item from the CIPP Reporting database
5+
6+
.DESCRIPTION
7+
Removes a specific item from the CippReportingDB table using partition key (tenant) and row key (item ID)
8+
9+
.PARAMETER TenantFilter
10+
The tenant domain or GUID (partition key)
11+
12+
.PARAMETER Type
13+
The type of data being removed (used to find and update count)
14+
15+
.PARAMETER ItemId
16+
The item ID or identifier to remove (used in row key)
17+
18+
.EXAMPLE
19+
Remove-CIPPDbItem -TenantFilter 'contoso.onmicrosoft.com' -Type 'MailboxRules' -ItemId 'rule-id-123'
20+
#>
21+
[CmdletBinding()]
22+
param(
23+
[Parameter(Mandatory = $true)]
24+
[string]$TenantFilter,
25+
26+
[Parameter(Mandatory = $true)]
27+
[string]$Type,
28+
29+
[Parameter(Mandatory = $true)]
30+
[string]$ItemId
31+
)
32+
33+
try {
34+
$Table = Get-CippTable -tablename 'CippReportingDB'
35+
36+
# Sanitize the ItemId for RowKey (same as in Add-CIPPDbItem)
37+
$SanitizedId = $ItemId -replace '[/\\#?]', '_' -replace '[\u0000-\u001F\u007F-\u009F]', ''
38+
$RowKey = "$Type-$SanitizedId"
39+
40+
# Try to get the entity
41+
$Filter = "PartitionKey eq '$TenantFilter' and RowKey eq '$RowKey'"
42+
$Entity = Get-CIPPAzDataTableEntity @Table -Filter $Filter
43+
44+
if ($Entity) {
45+
# Remove the entity
46+
Remove-AzDataTableEntity @Table -Entity $Entity -Force
47+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Removed $Type item with ID: $ItemId" -sev Debug
48+
49+
# Always decrement count
50+
try {
51+
$CountRowKey = "$Type-Count"
52+
$CountFilter = "PartitionKey eq '$TenantFilter' and RowKey eq '$CountRowKey'"
53+
$CountEntity = Get-CIPPAzDataTableEntity @Table -Filter $CountFilter
54+
55+
if ($CountEntity -and $CountEntity.DataCount -gt 0) {
56+
$CountEntity.DataCount = [int]$CountEntity.DataCount - 1
57+
Add-CIPPAzDataTableEntity @Table -Entity @{
58+
PartitionKey = $CountEntity.PartitionKey
59+
RowKey = $CountEntity.RowKey
60+
DataCount = $CountEntity.DataCount
61+
ETag = $CountEntity.ETag
62+
} -Force | Out-Null
63+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Decremented $Type count to $($CountEntity.DataCount)" -sev Debug
64+
}
65+
} catch {
66+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Failed to decrement count for $Type : $($_.Exception.Message)" -sev Warning
67+
}
68+
} else {
69+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Item not found for removal: $Type with ID $ItemId" -sev Debug
70+
}
71+
72+
} catch {
73+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Failed to remove $Type item: $($_.Exception.Message)" -sev Error -LogData (Get-CippException -Exception $_)
74+
throw
75+
}
76+
}

Modules/CIPPCore/Public/Remove-CIPPMailboxRule.ps1

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ function Remove-CIPPMailboxRule {
2222
Write-LogMessage -headers $Headers -API $APIName -message $Message -Sev 'Info' -tenant $TenantFilter
2323
return $Message
2424
} else {
25-
ForEach ($rule in $Rules) {
25+
foreach ($rule in $Rules) {
2626
$null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-InboxRule' -Anchor $Username -cmdParams @{Identity = $rule.Identity }
2727
}
2828
$Message = "Successfully deleted all rules for $($Username)"
@@ -41,6 +41,14 @@ function Remove-CIPPMailboxRule {
4141
$null = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Remove-InboxRule' -Anchor $Username -cmdParams @{Identity = $RuleId }
4242
$Message = "Successfully deleted mailbox rule $($RuleName) for $($Username)"
4343
Write-LogMessage -headers $Headers -API $APIName -message "Deleted mailbox rule $($RuleName) for $($Username)" -Sev 'Info' -tenant $TenantFilter
44+
45+
# Remove from cache if it exists
46+
try {
47+
Remove-CIPPDbItem -TenantFilter $TenantFilter -Type 'MailboxRules' -ItemId $RuleId
48+
} catch {
49+
Write-LogMessage -headers $Headers -API $APIName -message "Rule deleted but failed to remove from cache: $($_.Exception.Message)" -Sev 'Warning' -tenant $TenantFilter
50+
}
51+
4452
return $Message
4553
} catch {
4654
$ErrorMessage = Get-CippException -Exception $_

0 commit comments

Comments
 (0)