Skip to content

Commit 4a466be

Browse files
committed
fix: prevent stale template list from skewing applied standards report
1 parent 0bc4f50 commit 4a466be

2 files changed

Lines changed: 70 additions & 0 deletions

File tree

Modules/CIPPHTTP/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ListStandardsCompare.ps1

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,26 @@ function Invoke-ListStandardsCompare {
1313
$TenantFilter = $Request.Query.tenantFilter
1414
$TemplateFilter = $Request.Query.templateId
1515

16+
# Get-CIPPStandards is the authoritative source for what is currently in scope.
17+
$StandardParams = @{}
18+
if ($TemplateFilter) { $StandardParams.TemplateId = $TemplateFilter }
19+
if ($TenantFilter) { $StandardParams.TenantFilter = $TenantFilter }
20+
$StandardList = Get-CIPPStandards @StandardParams
21+
22+
$ScopedTemplateGuids = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
23+
$ScopedQuarantineNames = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
24+
foreach ($Entry in $StandardList) {
25+
switch ($Entry.Standard) {
26+
{ $_ -in @('IntuneTemplate', 'ConditionalAccessTemplate') } {
27+
if ($Entry.Settings.TemplateList.value) { $null = $ScopedTemplateGuids.Add($Entry.Settings.TemplateList.value) }
28+
}
29+
'QuarantineTemplate' {
30+
$DisplayName = $Entry.Settings.displayName.value ?? $Entry.Settings.displayName
31+
if ($DisplayName) { $null = $ScopedQuarantineNames.Add($DisplayName) }
32+
}
33+
}
34+
}
35+
1636
$Filters = [system.collections.generic.list[string]]::new()
1737
if ($TenantFilter) {
1838
$Filters.Add("PartitionKey eq '{0}'" -f $TenantFilter)
@@ -34,6 +54,20 @@ function Invoke-ListStandardsCompare {
3454
$FieldValue = $Standard.Value
3555
$Tenant = $Standard.PartitionKey
3656

57+
# Skip rows for template types no longer in scope per the current standard list.
58+
if ($FieldName -match '^standards\.(IntuneTemplate|ConditionalAccessTemplate)\.(.+)$') {
59+
if (-not $ScopedTemplateGuids.Contains($Matches[2])) { continue }
60+
} elseif ($ScopedQuarantineNames.Count -gt 0 -and $FieldName -match '^standards\.QuarantineTemplate\.(.+)$') {
61+
# Decode hex-encoded display name and check if it's still in scope
62+
$HexEncoded = $Matches[1]
63+
$Chars = [System.Collections.Generic.List[char]]::new()
64+
for ($i = 0; $i -lt $HexEncoded.Length; $i += 2) {
65+
$Chars.Add([char][Convert]::ToInt32($HexEncoded.Substring($i, 2), 16))
66+
}
67+
$DecodedName = -join $Chars
68+
if (-not $ScopedQuarantineNames.Contains($DecodedName)) { continue }
69+
}
70+
3771
# decode field names that are hex encoded (e.g. QuarantineTemplates)
3872
if ($FieldName -match '^(standards\.QuarantineTemplate\.)(.+)$') {
3973
$Prefix = $Matches[1]

Modules/CIPPHTTP/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-listStandardTemplates.ps1

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,42 @@ function Invoke-listStandardTemplates {
3535
$Data.excludedTenants = @()
3636
}
3737
}
38+
39+
# Re-expand TemplateList-Tags live so stale addedFields snapshots don't show removed templates
40+
if ($Data.standards) {
41+
foreach ($StandardName in $Data.standards.PSObject.Properties.Name) {
42+
$StandardConfig = $Data.standards.$StandardName
43+
$Items = if ($StandardConfig -is [System.Collections.IEnumerable] -and $StandardConfig -isnot [string]) { $StandardConfig } else { @($StandardConfig) }
44+
foreach ($Item in $Items) {
45+
if ($Item.'TemplateList-Tags' -and $Item.'TemplateList-Tags'.value) {
46+
if (-not $IntuneTemplatesCache) {
47+
$IntuneTable = Get-CippTable -tablename 'templates'
48+
$IntuneFilter = "PartitionKey eq 'IntuneTemplate'"
49+
$IntuneTemplatesCache = Get-CIPPAzDataTableEntity @IntuneTable -Filter $IntuneFilter
50+
}
51+
$PackageName = $Item.'TemplateList-Tags'.value
52+
$LiveExpanded = @($IntuneTemplatesCache | Where-Object package -EQ $PackageName | ForEach-Object {
53+
$TplJson = $_.JSON | ConvertFrom-Json -ErrorAction SilentlyContinue
54+
[pscustomobject]@{
55+
GUID = $_.RowKey
56+
displayName = if ($TplJson.displayName) { $TplJson.displayName } else { $_.RowKey }
57+
name = if ($TplJson.displayName) { $TplJson.displayName } else { $_.RowKey }
58+
}
59+
})
60+
if ($Item.'TemplateList-Tags'.addedFields) {
61+
$Item.'TemplateList-Tags'.addedFields | Add-Member -NotePropertyName 'templates' -NotePropertyValue $LiveExpanded -Force
62+
}
63+
if ($Item.'TemplateList-Tags'.rawData) {
64+
$Item.'TemplateList-Tags'.rawData | Add-Member -NotePropertyName 'templates' -NotePropertyValue $LiveExpanded -Force
65+
}
66+
if (-not $Item.'TemplateList-Tags'.addedFields -and -not $Item.'TemplateList-Tags'.rawData) {
67+
$Item.'TemplateList-Tags' | Add-Member -NotePropertyName 'addedFields' -NotePropertyValue ([pscustomobject]@{ templates = $LiveExpanded }) -Force
68+
}
69+
}
70+
}
71+
}
72+
}
73+
3874
$Data
3975
}
4076
} | Sort-Object -Property templateName

0 commit comments

Comments
 (0)