Fix Defender policy detection for new ADMX paths and add registry fallback (#81)

This commit is contained in:
Przemysław Kłys
2026-02-18 11:39:31 +01:00
parent 95789953a8
commit 3a69d14354
4 changed files with 131 additions and 7 deletions
+7
View File
@@ -1,5 +1,12 @@
# GPOZaurr Release History # GPOZaurr Release History
## Unreleased
- Fix `WindowsDefender` content detection for newer ADMX categories by supporting both:
- `Windows Components/Windows Defender*`
- `Windows Components/Microsoft Defender Antivirus*`
- Fix `WindowsDefenderExploitGuard` detection for legacy/new category naming variants.
- Add Defender registry fallback parsing (`SOFTWARE\Microsoft\Windows Defender*`) so Defender settings that land in `RegistrySettings` are still surfaced in `WindowsDefender` report output. [#81](https://github.com/EvotecIT/GPOZaurr/issues/81)
## 1.1.9 - 2024.12.02 ## 1.1.9 - 2024.12.02
- Fixes `Invoke-GPOZaurr` when using SplitReports without path [#58](https://github.com/EvotecIT/GPOZaurr/issues/58) - Fixes `Invoke-GPOZaurr` when using SplitReports without path [#58](https://github.com/EvotecIT/GPOZaurr/issues/58)
@@ -0,0 +1,39 @@
function ConvertTo-XMLRegistryDefenderOnReport {
<#
.SYNOPSIS
Converts Defender-related raw registry settings from the RegistrySettings report.
.DESCRIPTION
This function is used as a fallback for Defender settings that are not exposed as
policy categories but are still present in RegistrySettings output.
.PARAMETER GPO
RegistrySettings report object generated by ConvertTo-XMLRegistrySettings -SingleObject.
#>
[cmdletBinding()]
param(
[PSCustomObject] $GPO
)
foreach ($Registry in $GPO.Settings) {
if ($Registry.Key -like 'SOFTWARE\Microsoft\Windows Defender*') {
[PSCustomObject] [ordered] @{
DisplayName = $GPO.DisplayName
DomainName = $GPO.DomainName
GUID = $GPO.GUID
GpoType = $GPO.GpoType
FallbackSource = 'RegistrySettings'
Hive = $Registry.Hive
Key = $Registry.Key
Name = $Registry.Name
Type = $Registry.Type
Value = $Registry.Value
Changed = $Registry.Changed
Filters = $Registry.Filters
Linked = $GPO.Linked
LinksCount = $GPO.LinksCount
Links = $GPO.Links
}
}
}
}
+20 -6
View File
@@ -1170,12 +1170,23 @@
Settings = 'Policy' Settings = 'Policy'
} }
) )
GPOPath = 'Policies -> Administrative Templates -> Windows Components/Windows Defender' ByReports = @(
@{
Report = 'RegistrySettings'
}
)
GPOPath = @(
'Policies -> Administrative Templates -> Windows Components/Windows Defender'
'Policies -> Administrative Templates -> Windows Components/Microsoft Defender Antivirus'
)
Code = { Code = {
ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Windows Defender*' ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Windows Defender*', 'Windows Components/Microsoft Defender Antivirus*'
} }
CodeSingle = { CodeSingle = {
ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Windows Defender*' -SingleObject ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Windows Defender*', 'Windows Components/Microsoft Defender Antivirus*' -SingleObject
}
CodeReport = {
ConvertTo-XMLRegistryDefenderOnReport -GPO $GPO
} }
} }
WindowsDefenderExploitGuard = @{ WindowsDefenderExploitGuard = @{
@@ -1186,12 +1197,15 @@
Settings = 'Policy' Settings = 'Policy'
} }
) )
GPOPath = 'Policies -> Administrative Templates -> Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard' GPOPath = @(
'Policies -> Administrative Templates -> Windows Components/Windows Defender/Windows Defender Exploit Guard'
'Policies -> Administrative Templates -> Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard'
)
Code = { Code = {
ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard*' ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Windows Defender*/Windows Defender Exploit Guard*', 'Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard*', 'Windows Components/Microsoft Defender Antivirus/Windows Defender Exploit Guard*'
} }
CodeSingle = { CodeSingle = {
ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard*' -SingleObject ConvertTo-XMLGenericPolicy -GPO $GPO -Category 'Windows Components/Windows Defender*/Windows Defender Exploit Guard*', 'Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard*', 'Windows Components/Microsoft Defender Antivirus/Windows Defender Exploit Guard*' -SingleObject
} }
} }
# WindowsFirewall = @{ # WindowsFirewall = @{
+64
View File
@@ -0,0 +1,64 @@
Describe 'Defender content detection' {
BeforeAll {
Import-Module $PSScriptRoot\..\*.psd1 -Force
}
It 'WindowsDefender dictionary supports old and new categories' {
InModuleScope GPOZaurr {
$Entry = $Script:GPODitionary['WindowsDefender']
$Entry.GPOPath | Should -Contain 'Policies -> Administrative Templates -> Windows Components/Windows Defender'
$Entry.GPOPath | Should -Contain 'Policies -> Administrative Templates -> Windows Components/Microsoft Defender Antivirus'
$Entry.ByReports.Report | Should -Contain 'RegistrySettings'
$Entry.CodeReport.ToString() | Should -Match 'ConvertTo-XMLRegistryDefenderOnReport'
}
}
It 'WindowsDefenderExploitGuard supports category variants' {
InModuleScope GPOZaurr {
$Entry = $Script:GPODitionary['WindowsDefenderExploitGuard']
$Entry.GPOPath | Should -Contain 'Policies -> Administrative Templates -> Windows Components/Windows Defender/Windows Defender Exploit Guard'
$Entry.GPOPath | Should -Contain 'Policies -> Administrative Templates -> Windows Components/Microsoft Defender Antivirus/Microsoft Defender Exploit Guard'
$Entry.Code.ToString() | Should -Match 'Windows Components/Microsoft Defender Antivirus/Windows Defender Exploit Guard\*'
}
}
It 'ConvertTo-XMLRegistryDefenderOnReport returns only Defender registry settings' {
InModuleScope GPOZaurr {
$GPO = [PSCustomObject] @{
DisplayName = 'Test Defender GPO'
DomainName = 'contoso.com'
GUID = '11111111-1111-1111-1111-111111111111'
GpoType = 'Computer'
Linked = $true
LinksCount = 1
Links = @('OU=Workstations,DC=contoso,DC=com')
Settings = @(
[PSCustomObject] @{
Hive = 'HKEY_LOCAL_MACHINE'
Key = 'SOFTWARE\Microsoft\Windows Defender\MpEngine'
Name = 'MpFolderScanThreadCount'
Type = 'REG_DWORD'
Value = '4'
Changed = [datetime] '2026-02-18T11:15:00'
Filters = $null
}
[PSCustomObject] @{
Hive = 'HKEY_LOCAL_MACHINE'
Key = 'SOFTWARE\Contoso\Other'
Name = 'Setting'
Type = 'REG_SZ'
Value = 'Value'
Changed = [datetime] '2026-02-18T11:15:00'
Filters = $null
}
)
}
[Array] $Result = ConvertTo-XMLRegistryDefenderOnReport -GPO $GPO
$Result.Count | Should -Be 1
$Result[0].FallbackSource | Should -Be 'RegistrySettings'
$Result[0].Key | Should -Be 'SOFTWARE\Microsoft\Windows Defender\MpEngine'
$Result[0].Name | Should -Be 'MpFolderScanThreadCount'
}
}
}