Skip to content

Commit e9576d3

Browse files
Add data collection for tests
1 parent 968ed82 commit e9576d3

27 files changed

+1098
-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: 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 'CippReportTemplates'
30+
$Filter = "PartitionKey eq 'ReportTemplate' 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+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
function Start-CIPPDBCacheOrchestrator {
2+
<#
3+
.SYNOPSIS
4+
Orchestrates database cache collection across all tenants
5+
6+
.DESCRIPTION
7+
Creates per-tenant jobs to collect and cache Microsoft Graph data
8+
9+
.FUNCTIONALITY
10+
Entrypoint
11+
#>
12+
[CmdletBinding()]
13+
param()
14+
15+
try {
16+
Write-LogMessage -API 'CIPPDBCache' -message 'Starting database cache orchestration' -sev Info
17+
18+
$TenantList = Get-Tenants | Where-Object { $_.defaultDomainName -ne $null }
19+
20+
if ($TenantList.Count -eq 0) {
21+
Write-LogMessage -API 'CIPPDBCache' -message 'No tenants found for cache collection' -sev Warning
22+
return
23+
}
24+
25+
$Queue = New-CippQueueEntry -Name 'Database Cache Collection' -TotalTasks $TenantList.Count
26+
27+
$Batch = foreach ($Tenant in $TenantList) {
28+
[PSCustomObject]@{
29+
FunctionName = 'Push-CIPPDBCacheData'
30+
TenantFilter = $Tenant.defaultDomainName
31+
QueueId = $Queue.RowKey
32+
QueueName = "DB Cache - $($Tenant.defaultDomainName)"
33+
}
34+
}
35+
36+
$InputObject = [PSCustomObject]@{
37+
Batch = @($Batch)
38+
OrchestratorName = 'CIPPDBCacheOrchestrator'
39+
SkipLog = $false
40+
}
41+
42+
Start-NewOrchestration -FunctionName 'CIPPOrchestrator' -InputObject ($InputObject | ConvertTo-Json -Compress -Depth 5)
43+
44+
Write-LogMessage -API 'CIPPDBCache' -message "Queued database cache collection for $($TenantList.Count) tenants" -sev Info
45+
46+
} catch {
47+
Write-LogMessage -API 'CIPPDBCache' -message "Failed to start orchestration: $($_.Exception.Message)" -sev Error
48+
throw
49+
}
50+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
function Get-CIPPDbItem {
2+
<#
3+
.SYNOPSIS
4+
Get specific items from the CIPP Reporting database
5+
6+
.DESCRIPTION
7+
Retrieves items from the CippReportingDB table using partition key (tenant) and type
8+
9+
.PARAMETER TenantFilter
10+
The tenant domain or GUID (partition key)
11+
12+
.PARAMETER Type
13+
The type of data to retrieve (used in row key filter)
14+
15+
.PARAMETER CountsOnly
16+
If specified, returns all count rows for the tenant
17+
18+
.EXAMPLE
19+
Get-CIPPDbItem -TenantFilter 'contoso.onmicrosoft.com' -Type 'Groups'
20+
21+
.EXAMPLE
22+
Get-CIPPDbItem -TenantFilter 'contoso.onmicrosoft.com' -CountsOnly
23+
#>
24+
[CmdletBinding()]
25+
param(
26+
[Parameter(Mandatory = $true)]
27+
[string]$TenantFilter,
28+
29+
[Parameter(Mandatory = $false)]
30+
[string]$Type,
31+
32+
[Parameter(Mandatory = $false)]
33+
[switch]$CountsOnly
34+
)
35+
36+
try {
37+
$Table = Get-CippTable -tablename 'CippReportingDB'
38+
39+
if ($CountsOnly) {
40+
$Filter = "PartitionKey eq '{0}'" -f $TenantFilter
41+
$Results = Get-CIPPAzDataTableEntity @Table -Filter $Filter
42+
$Results = $Results | Where-Object { $_.RowKey -like '*-Count' }
43+
} else {
44+
if (-not $Type) {
45+
throw 'Type parameter is required when CountsOnly is not specified'
46+
}
47+
$Filter = "PartitionKey eq '{0}' and RowKey ge '{1}-' and RowKey lt '{1}.'" -f $TenantFilter, $Type
48+
$Results = Get-CIPPAzDataTableEntity @Table -Filter $Filter
49+
}
50+
51+
return $Results
52+
53+
} catch {
54+
Write-LogMessage -API 'CIPPDbItem' -tenant $TenantFilter -message "Failed to get items$(if ($Type) { " of type $Type" })$(if ($CountsOnly) { ' (counts only)' }): $($_.Exception.Message)" -sev Error
55+
throw
56+
}
57+
}

0 commit comments

Comments
 (0)