Skip to content

Commit 3116d49

Browse files
authored
Merge pull request #638 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 4478bcb + a4633fe commit 3116d49

28 files changed

+1209
-0
lines changed

CIPPTimers.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,5 +222,14 @@
222222
"Priority": 21,
223223
"RunOnProcessor": true,
224224
"IsSystem": true
225+
},
226+
{
227+
"Id": "9a7f8e6d-5c4b-3a2d-1e0f-9b8c7d6e5f4a",
228+
"Command": "Start-CIPPDBCacheOrchestrator",
229+
"Description": "Timer to collect and cache Microsoft Graph data for all tenants",
230+
"Cron": "0 0 3 * * *",
231+
"Priority": 22,
232+
"RunOnProcessor": true,
233+
"IsSystem": true
225234
}
226235
]
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
function Add-CIPPDbItem {
2+
<#
3+
.SYNOPSIS
4+
Add items to the CIPP Reporting database
5+
6+
.DESCRIPTION
7+
Adds items to the CippReportingDB table with support for bulk inserts and count mode
8+
9+
.PARAMETER TenantFilter
10+
The tenant domain or GUID (used as partition key)
11+
12+
.PARAMETER Type
13+
The type of data being stored (used in row key)
14+
15+
.PARAMETER Data
16+
Array of items to add to the database
17+
18+
.PARAMETER Count
19+
If specified, stores a single row with count of each object property as separate properties
20+
21+
.EXAMPLE
22+
Add-CIPPDbItem -TenantFilter 'contoso.onmicrosoft.com' -Type 'Groups' -Data $GroupsData
23+
24+
.EXAMPLE
25+
Add-CIPPDbItem -TenantFilter 'contoso.onmicrosoft.com' -Type 'Groups' -Data $GroupsData -Count
26+
#>
27+
[CmdletBinding()]
28+
param(
29+
[Parameter(Mandatory = $true)]
30+
[string]$TenantFilter,
31+
32+
[Parameter(Mandatory = $true)]
33+
[string]$Type,
34+
35+
[Parameter(Mandatory = $true)]
36+
[AllowEmptyCollection()]
37+
[array]$Data,
38+
39+
[Parameter(Mandatory = $false)]
40+
[switch]$Count
41+
)
42+
43+
try {
44+
$Table = Get-CippTable -tablename 'CippReportingDB'
45+
46+
if ($Count) {
47+
$Entity = @{
48+
PartitionKey = $TenantFilter
49+
RowKey = "$Type-Count"
50+
DataCount = [int]$Data.Count
51+
}
52+
53+
Add-CIPPAzDataTableEntity @Table -Entity $Entity -Force | Out-Null
54+
55+
} else {
56+
$Entities = foreach ($Item in $Data) {
57+
$ItemId = $Item.id
58+
@{
59+
PartitionKey = $TenantFilter
60+
RowKey = "$Type-$ItemId"
61+
Data = [string]($Item | ConvertTo-Json -Depth 10 -Compress)
62+
Type = $Type
63+
}
64+
}
65+
66+
$BatchSize = 1000
67+
for ($i = 0; $i -lt $Entities.Count; $i += $BatchSize) {
68+
$Batch = $Entities[$i..([Math]::Min($i + $BatchSize - 1, $Entities.Count - 1))]
69+
foreach ($Entity in $Batch) {
70+
Add-CIPPAzDataTableEntity @Table -Entity $Entity -Force | Out-Null
71+
}
72+
}
73+
}
74+
75+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Added $($Data.Count) items of type $Type$(if ($Count) { ' (count mode)' })" -sev Info
76+
77+
} catch {
78+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Failed to add items of type $Type : $($_.Exception.Message)" -sev Error
79+
throw
80+
}
81+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
function Add-CippTestResult {
2+
<#
3+
.SYNOPSIS
4+
Adds a test result to the CIPP test results database
5+
6+
.DESCRIPTION
7+
Stores test result data in the CippTestResults table with tenant and test ID as keys
8+
9+
.PARAMETER TenantFilter
10+
The tenant domain or GUID for the test result
11+
12+
.PARAMETER TestId
13+
Unique identifier for the test
14+
15+
.PARAMETER Status
16+
Test status (e.g., Pass, Fail, Skip)
17+
18+
.PARAMETER ResultMarkdown
19+
Markdown formatted result details
20+
21+
.PARAMETER Risk
22+
Risk level (e.g., High, Medium, Low)
23+
24+
.PARAMETER Name
25+
Display name of the test
26+
27+
.PARAMETER Pillar
28+
Security pillar category
29+
30+
.PARAMETER UserImpact
31+
Impact level on users
32+
33+
.PARAMETER ImplementationEffort
34+
Effort required for implementation
35+
36+
.PARAMETER Category
37+
Test category or classification
38+
39+
.EXAMPLE
40+
Add-CippTestResult -TenantFilter 'contoso.onmicrosoft.com' -TestId 'MFA-001' -Status 'Pass' -Name 'MFA Enabled' -Risk 'High'
41+
#>
42+
[CmdletBinding()]
43+
param(
44+
[Parameter(Mandatory = $true)]
45+
[string]$TenantFilter,
46+
47+
[Parameter(Mandatory = $true)]
48+
[string]$TestId,
49+
50+
[Parameter(Mandatory = $true)]
51+
[string]$Status,
52+
53+
[Parameter(Mandatory = $false)]
54+
[string]$ResultMarkdown,
55+
56+
[Parameter(Mandatory = $false)]
57+
[string]$Risk,
58+
59+
[Parameter(Mandatory = $false)]
60+
[string]$Name,
61+
62+
[Parameter(Mandatory = $false)]
63+
[string]$Pillar,
64+
65+
[Parameter(Mandatory = $false)]
66+
[string]$UserImpact,
67+
68+
[Parameter(Mandatory = $false)]
69+
[string]$ImplementationEffort,
70+
71+
[Parameter(Mandatory = $false)]
72+
[string]$Category
73+
)
74+
75+
try {
76+
$Table = Get-CippTable -tablename 'CippTestResults'
77+
78+
$Entity = @{
79+
PartitionKey = $TenantFilter
80+
RowKey = $TestId
81+
Status = $Status
82+
ResultMarkdown = $ResultMarkdown ?? ''
83+
Risk = $Risk ?? ''
84+
Name = $Name ?? ''
85+
Pillar = $Pillar ?? ''
86+
UserImpact = $UserImpact ?? ''
87+
ImplementationEffort = $ImplementationEffort ?? ''
88+
Category = $Category ?? ''
89+
}
90+
91+
Add-CIPPAzDataTableEntity @Table -Entity $Entity -Force
92+
Write-LogMessage -API 'CIPPTestResults' -tenant $TenantFilter -message "Added test result: $TestId - $Status" -sev Info
93+
} catch {
94+
Write-LogMessage -API 'CIPPTestResults' -tenant $TenantFilter -message "Failed to add test result: $($_.Exception.Message)" -sev Error
95+
throw
96+
}
97+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
function Push-CIPPDBCacheData {
2+
<#
3+
.SYNOPSIS
4+
Activity function to collect and cache all data for a single tenant
5+
6+
.DESCRIPTION
7+
Calls all collection functions sequentially, storing data immediately after each collection
8+
9+
.FUNCTIONALITY
10+
Entrypoint
11+
#>
12+
[CmdletBinding()]
13+
param($Item)
14+
15+
$TenantFilter = $Item.TenantFilter
16+
#This collects all data for a tenant and caches it in the CIPP Reporting database. DO NOT ADD PROCESSING OR LOGIC HERE.
17+
#The point of this file is to always be <10 minutes execution time.
18+
try {
19+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Starting database cache collection for tenant' -sev Info
20+
21+
try { Set-CIPPDBCacheUsers -TenantFilter $TenantFilter } catch {
22+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Users collection failed: $($_.Exception.Message)" -sev Error
23+
}
24+
25+
try { Set-CIPPDBCacheGroups -TenantFilter $TenantFilter } catch {
26+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Groups collection failed: $($_.Exception.Message)" -sev Error
27+
}
28+
29+
try { Set-CIPPDBCacheGuests -TenantFilter $TenantFilter } catch {
30+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Guests collection failed: $($_.Exception.Message)" -sev Error
31+
}
32+
33+
try { Set-CIPPDBCacheServicePrincipals -TenantFilter $TenantFilter } catch {
34+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "ServicePrincipals collection failed: $($_.Exception.Message)" -sev Error
35+
}
36+
37+
try { Set-CIPPDBCacheApps -TenantFilter $TenantFilter } catch {
38+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Apps collection failed: $($_.Exception.Message)" -sev Error
39+
}
40+
41+
try { Set-CIPPDBCacheDevices -TenantFilter $TenantFilter } catch {
42+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Devices collection failed: $($_.Exception.Message)" -sev Error
43+
}
44+
45+
try { Set-CIPPDBCacheManagedDevices -TenantFilter $TenantFilter } catch {
46+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "ManagedDevices collection failed: $($_.Exception.Message)" -sev Error
47+
}
48+
49+
try { Set-CIPPDBCacheOrganization -TenantFilter $TenantFilter } catch {
50+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Organization collection failed: $($_.Exception.Message)" -sev Error
51+
}
52+
53+
try { Set-CIPPDBCacheRoles -TenantFilter $TenantFilter } catch {
54+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Roles collection failed: $($_.Exception.Message)" -sev Error
55+
}
56+
57+
try { Set-CIPPDBCacheAdminConsentRequestPolicy -TenantFilter $TenantFilter } catch {
58+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "AdminConsentRequestPolicy collection failed: $($_.Exception.Message)" -sev Error
59+
}
60+
61+
try { Set-CIPPDBCacheDeviceSettings -TenantFilter $TenantFilter } catch {
62+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "DeviceSettings collection failed: $($_.Exception.Message)" -sev Error
63+
}
64+
65+
try { Set-CIPPDBCacheDirectoryRecommendations -TenantFilter $TenantFilter } catch {
66+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "DirectoryRecommendations collection failed: $($_.Exception.Message)" -sev Error
67+
}
68+
69+
try { Set-CIPPDBCacheCrossTenantAccessPolicy -TenantFilter $TenantFilter } catch {
70+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "CrossTenantAccessPolicy collection failed: $($_.Exception.Message)" -sev Error
71+
}
72+
73+
try { Set-CIPPDBCacheDefaultAppManagementPolicy -TenantFilter $TenantFilter } catch {
74+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "DefaultAppManagementPolicy collection failed: $($_.Exception.Message)" -sev Error
75+
}
76+
77+
try { Set-CIPPDBCacheSettings -TenantFilter $TenantFilter } catch {
78+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Settings collection failed: $($_.Exception.Message)" -sev Error
79+
}
80+
81+
try { Set-CIPPDBCacheSecureScore -TenantFilter $TenantFilter } catch {
82+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "SecureScore collection failed: $($_.Exception.Message)" -sev Error
83+
}
84+
85+
try { Set-CIPPDBCacheIntunePolicies -TenantFilter $TenantFilter } catch {
86+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "IntunePolicies collection failed: $($_.Exception.Message)" -sev Error
87+
}
88+
89+
try { Set-CIPPDBCacheConditionalAccessPolicies -TenantFilter $TenantFilter } catch {
90+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "ConditionalAccessPolicies collection failed: $($_.Exception.Message)" -sev Error
91+
}
92+
93+
try { Set-CIPPDBCachePIMSettings -TenantFilter $TenantFilter } catch {
94+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "PIMSettings collection failed: $($_.Exception.Message)" -sev Error
95+
}
96+
97+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Completed database cache collection for tenant' -sev Info
98+
99+
} catch {
100+
$ErrorMessage = Get-CippException -Exception $_
101+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Failed to complete database cache collection: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
102+
}
103+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
function Invoke-ListTests {
2+
<#
3+
.SYNOPSIS
4+
Lists tests for a tenant, optionally filtered by report ID
5+
6+
.FUNCTIONALITY
7+
Entrypoint
8+
9+
.ROLE
10+
Tenant.Reports.Read
11+
#>
12+
[CmdletBinding()]
13+
param($Request, $TriggerMetadata)
14+
15+
$APIName = $TriggerMetadata.FunctionName
16+
Write-LogMessage -user $request.headers.'x-ms-client-principal' -API $APINAME -message 'Accessed this API' -Sev 'Debug'
17+
18+
try {
19+
$TenantFilter = $Request.Query.tenantFilter ?? $Request.Body.tenantFilter
20+
$ReportId = $Request.Query.reportId ?? $Request.Body.reportId
21+
22+
if (-not $TenantFilter) {
23+
throw 'TenantFilter parameter is required'
24+
}
25+
26+
$TestResultsData = Get-CIPPTestResults -TenantFilter $TenantFilter
27+
28+
if ($ReportId) {
29+
$ReportTable = Get-CippTable -tablename 'CippReportingTemplates'
30+
$Filter = "PartitionKey eq 'ReportingTemplate' and RowKey eq '{0}'" -f $ReportId
31+
$ReportTemplate = Get-CIPPAzDataTableEntity @ReportTable -Filter $Filter
32+
33+
if ($ReportTemplate) {
34+
$ReportTests = $ReportTemplate.Tests | ConvertFrom-Json
35+
$FilteredTests = $TestResultsData.TestResults | Where-Object { $ReportTests -contains $_.TestId }
36+
$TestResultsData.TestResults = $FilteredTests
37+
} else {
38+
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Report template '$ReportId' not found" -sev Warning
39+
$TestResultsData.TestResults = @()
40+
}
41+
}
42+
43+
$TestCounts = @{
44+
Successful = @($TestResultsData.TestResults | Where-Object { $_.Result -eq 'Passed' }).Count
45+
Failed = @($TestResultsData.TestResults | Where-Object { $_.Result -eq 'Failed' }).Count
46+
Skipped = @($TestResultsData.TestResults | Where-Object { $_.Result -eq 'Skipped' }).Count
47+
Total = @($TestResultsData.TestResults).Count
48+
}
49+
50+
$TestResultsData | Add-Member -NotePropertyName 'TestCounts' -NotePropertyValue $TestCounts -Force
51+
52+
$StatusCode = [HttpStatusCode]::OK
53+
$Body = $TestResultsData
54+
55+
} catch {
56+
$ErrorMessage = Get-CippException -Exception $_
57+
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Error retrieving tests: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
58+
$StatusCode = [HttpStatusCode]::BadRequest
59+
$Body = @{ Error = $ErrorMessage.NormalizedError }
60+
}
61+
62+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
63+
StatusCode = $StatusCode
64+
Body = $Body
65+
})
66+
}

0 commit comments

Comments
 (0)