Skip to content

Commit 18d28ec

Browse files
authored
Fix: Intune bundle drift remediation (KelvinTegelaar#1982)
# Summary Fixes DeniedRemediate one-off drift remediation silently doing nothing for IntuneTemplate policies added via tag bundles (TemplateList-Tags). The scheduled task would complete "successfully" but the policy was never deployed to Intune. # Description `Invoke-ExecUpdateDriftDeviation` resolves the template settings for a DeniedRemediate one-off by filtering `standardSettings.IntuneTemplate` on `TemplateList.value`. For templates added individually this works, but for templates added via a tag bundle (e.g. "Core Policies (4 Templates)"), `TemplateList` is null and the templates live under `TemplateList Tags.rawData.templates` instead. The `Where-Object` returns nothing, `$Settings` ends up null, and the scheduled task calls `Invoke-CIPPStandardIntuneTemplate` with no settings. The function then wildcard-matches every template in the table and processes them as a single blob, which doesn't match anything in Graph. The fix adds a fallback that searches `TemplateList-Tags.rawData.templates` for the template GUID when the `TemplateList.value` lookup returns nothing. When found, it expands the bundle entry into a proper `TemplateList` with the individual GUID, matching the pattern `Get-CIPPStandards` already uses for bundle expansion during normal standards runs. Also added a warning log when neither path finds the template. # Testing 1. Create a drift template with a **tag bundle** containing multiple Intune templates (e.g. "Core Policies" with Config Refresh, LAPS, etc.) 2. Assign to a test tenant and run drift. Bundled policies should show as deviations if they don't exist in the tenant 3. Mark a bundled template deviation as "Denied" (DeniedRemediate) 4. Wait for the one-off scheduled task to complete (or force it to /w timer run) 5. Verify the policy is actually deployed in Intune (this is the bug fix, previously it silently did nothing) 6. Verify the policy has the correct assignments from the bundle entry 7. Also test an **individual** (non-bundled) template DeniedRemediate to confirm no regression on the original code path
2 parents 0e298ca + 686c0c1 commit 18d28ec

1 file changed

Lines changed: 23 additions & 5 deletions

File tree

Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-ExecUpdateDriftDeviation.ps1

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,28 @@ function Invoke-ExecUpdateDriftDeviation {
4646
if ($Setting -like '*IntuneTemplate*') {
4747
$Setting = 'IntuneTemplate'
4848
$TemplateId = $Deviation.standardName.split('.') | Select-Object -Index 2
49-
$StandardTemplate = $StandardTemplate.standardSettings.IntuneTemplate | Where-Object { $_.TemplateList.value -like "*$TemplateId*" }
50-
$StandardTemplate | Add-Member -MemberType NoteProperty -Name 'remediate' -Value $true -Force
51-
$StandardTemplate | Add-Member -MemberType NoteProperty -Name 'report' -Value $true -Force
52-
$Settings = $StandardTemplate
49+
$MatchedTemplate = $StandardTemplate.standardSettings.IntuneTemplate | Where-Object { $_.TemplateList.value -like "*$TemplateId*" } | Select-Object -First 1
50+
if (-not $MatchedTemplate) {
51+
# Template may be inside a TemplateList-Tags bundle, expand it
52+
$BundleEntry = $StandardTemplate.standardSettings.IntuneTemplate | Where-Object {
53+
$_.'TemplateList-Tags'.rawData.templates | Where-Object { $_.GUID -like "*$TemplateId*" }
54+
} | Select-Object -First 1
55+
if ($BundleEntry) {
56+
$MatchedTemplate = $BundleEntry.PSObject.Copy()
57+
$MatchedTemplate.PSObject.Properties.Remove('TemplateList-Tags')
58+
$MatchedTemplate | Add-Member -NotePropertyName TemplateList -NotePropertyValue ([pscustomobject]@{
59+
label = $TemplateId
60+
value = $TemplateId
61+
}) -Force
62+
}
63+
}
64+
if (-not $MatchedTemplate) {
65+
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Could not find IntuneTemplate $TemplateId in drift standard settings for remediation" -Sev 'Warn'
66+
} else {
67+
$MatchedTemplate | Add-Member -MemberType NoteProperty -Name 'remediate' -Value $true -Force
68+
$MatchedTemplate | Add-Member -MemberType NoteProperty -Name 'report' -Value $true -Force
69+
$Settings = $MatchedTemplate
70+
}
5371
} elseif ($Setting -like '*ConditionalAccessTemplate*') {
5472
$Setting = 'ConditionalAccessTemplate'
5573
$TemplateId = $Deviation.standardName.split('.') | Select-Object -Index 2
@@ -91,7 +109,7 @@ function Invoke-ExecUpdateDriftDeviation {
91109
}
92110
}
93111
Add-CIPPScheduledTask -Task $TaskBody -hidden $false
94-
Write-LogMessage -tenant $TenantFilter -user $request.headers.'x-ms-client-principal' -API $APINAME -message "Scheduled drift remediation task for $Setting" -Sev 'Info'
112+
Write-LogMessage -tenant $TenantFilter -Headers $Request.Headers -API $APINAME -message "Scheduled drift remediation task for $Setting" -Sev 'Info'
95113

96114
if ($PersistentDeny) {
97115
$PersistentTaskBody = @{

0 commit comments

Comments
 (0)