Handle excluded domains and preserve GPO date filters (#91)

* Fix offline domain handling and date filters

* Make AD regression tests runner-independent
This commit is contained in:
Przemysław Kłys
2026-08-19 11:13:08 +02:00
committed by GitHub
parent efc7743906
commit 7bda3134af
4 changed files with 112 additions and 8 deletions
+16 -5
View File
@@ -41,10 +41,14 @@
foreach ($Domain in $ForestInformation.Domains) {
$ADDictionary[$Domain] = [ordered] @{}
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
$DomainInformation = Get-ADDomain -Server $QueryServer
if ($Type -contains 'DomainAdmins') {
$QueryServerInformation = $ForestInformation['QueryServers'][$Domain]
if (-not $QueryServerInformation -or -not $QueryServerInformation['HostName']) {
continue
}
$QueryServer = $QueryServerInformation['HostName'][0]
$DomainInformation = Get-ADDomain -Server $QueryServer
Get-ADGroup -Filter "SID -eq '$($DomainInformation.DomainSID)-512'" -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
$ADDictionary['ByNetBIOS']["$($DomainInformation.NetBIOSName)\$($_.Name)"] = $_
$ADDictionary[$Domain]['DomainAdmins'] = "$($DomainInformation.NetBIOSName)\$($_.Name)"
@@ -54,11 +58,18 @@
}
foreach ($Domain in $ForestInformation.Forest.Domains) {
if ($Domain -in $ExcludeDomains) {
continue
}
if (-not $ADDictionary[$Domain]) {
$ADDictionary[$Domain] = [ordered] @{}
}
if ($Type -contains 'EnterpriseAdmins') {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
$QueryServerInformation = $ForestInformation['QueryServers'][$Domain]
if (-not $QueryServerInformation -or -not $QueryServerInformation['HostName']) {
continue
}
$QueryServer = $QueryServerInformation['HostName'][0]
$DomainInformation = Get-ADDomain -Server $QueryServer
Get-ADGroup -Filter "SID -eq '$($DomainInformation.DomainSID)-519'" -Server $QueryServer -ErrorAction SilentlyContinue | ForEach-Object {
@@ -70,4 +81,4 @@
}
$ADDictionary
}
}
+3 -3
View File
@@ -106,7 +106,7 @@
$Splat['Filter'] = -join ($Splat['Filter'], ' -and ((WhenChanged -ge $DateFrom -and WhenChanged -le $DateTo) -or (WhenCreated -ge $DateFrom -and WhenCreated -le $DateTo))')
} elseif ($DateProperty -eq 'WhenChanged' -or $DateProperty -eq 'WhenCreated') {
$Property = $DateProperty[0]
$Splat['Filter'] = -join ($Splat['Filter'], ' -and ($Property -ge $DateFrom -and $Property -le $DateTo)')
$Splat['Filter'] = -join ($Splat['Filter'], " -and ($Property -ge `$DateFrom -and $Property -le `$DateTo)")
} else {
Write-Warning -Message "Get-GPOZaurrRedirect - DateProperty parameter is empty. Provide name and try again."
continue
@@ -118,7 +118,7 @@
$Splat['Filter'] = -join ($Splat['Filter'], ' -and ((WhenChanged -ge $DateFrom -and WhenChanged -le $DateTo) -or (WhenCreated -ge $DateFrom -and WhenCreated -le $DateTo))')
} elseif ($DateProperty -eq 'WhenChanged' -or $DateProperty -eq 'WhenCreated') {
$Property = $DateProperty[0]
$Splat['Filter'] = -join ($Splat['Filter'], ' -and ($Property -ge $DateFrom -and $Property -le $DateTo)')
$Splat['Filter'] = -join ($Splat['Filter'], " -and ($Property -ge `$DateFrom -and $Property -le `$DateTo)")
} else {
Write-Warning -Message "Get-GPOZaurrRedirect - DateProperty parameter is empty. Provide name and try again."
continue
@@ -161,4 +161,4 @@
End {
}
}
}
+50
View File
@@ -0,0 +1,50 @@
Describe 'Get-ADAdministrativeGroups domain filtering' {
BeforeAll {
Import-Module $PSScriptRoot\..\GPOZaurr.psm1 -Force
}
It 'skips excluded and unreachable domains without indexing missing query servers' {
InModuleScope GPOZaurr {
function Get-ADDomain {
param([string] $Server)
}
function Get-ADGroup {
param(
[string] $Filter,
[string] $Server,
[System.Management.Automation.ActionPreference] $ErrorAction
)
}
Mock Get-WinADForestDetails {
[ordered] @{
Forest = [PSCustomObject] @{ Domains = @('root.contoso.com', 'excluded.contoso.com', 'offline.contoso.com') }
Domains = @('root.contoso.com', 'offline.contoso.com')
QueryServers = @{
'root.contoso.com' = @{ HostName = @('dc1.root.contoso.com') }
}
}
}
Mock Get-ADDomain {
[PSCustomObject] @{
DomainSID = 'S-1-5-21-1-2-3'
NetBIOSName = 'ROOT'
}
}
Mock Get-ADGroup {
[PSCustomObject] @{
Name = if ($Filter -match '519') { 'Enterprise Admins' } else { 'Domain Admins' }
ObjectClass = 'group'
SID = [PSCustomObject] @{ Value = if ($Filter -match '519') { 'S-1-5-21-1-2-3-519' } else { 'S-1-5-21-1-2-3-512' } }
}
}
$Result = Get-ADAdministrativeGroups -Type DomainAdmins, EnterpriseAdmins -ExcludeDomains 'excluded.contoso.com'
$Result['ByNetBIOS'].Keys | Should -Contain 'ROOT\Domain Admins'
$Result['ByNetBIOS'].Keys | Should -Contain 'ROOT\Enterprise Admins'
$Result.Keys | Should -Not -Contain 'excluded.contoso.com'
Should -Invoke -CommandName Get-ADDomain -Times 2 -Exactly -ParameterFilter { $Server -eq 'dc1.root.contoso.com' }
}
}
}
+43
View File
@@ -0,0 +1,43 @@
Describe 'GPO date filters' {
BeforeAll {
Import-Module $PSScriptRoot\..\GPOZaurr.psm1 -Force
}
BeforeEach {
InModuleScope GPOZaurr {
Mock Get-WinADForestDetails {
[ordered] @{
Domains = @('root.contoso.com')
QueryServers = @{ 'root.contoso.com' = @{ HostName = @('dc1.root.contoso.com') } }
}
}
Mock Get-ChoosenDates {
[PSCustomObject] @{
DateFrom = [datetime] '2026-08-01'
DateTo = [datetime] '2026-08-08'
}
}
Mock Get-ADObject {}
}
}
It 'keeps DateTime variables intact in Get-GPOZaurrAD filters' {
InModuleScope GPOZaurr {
Get-GPOZaurrAD -DateRange Last7Days -DateProperty WhenCreated
Should -Invoke -CommandName Get-ADObject -Times 1 -Exactly -ParameterFilter {
$Filter -eq "(objectClass -eq 'groupPolicyContainer') -and (WhenCreated -ge `$DateFrom -and WhenCreated -le `$DateTo)"
}
}
}
It 'keeps DateTime variables intact in Get-GPOZaurrRedirect filters' {
InModuleScope GPOZaurr {
Get-GPOZaurrRedirect -DateRange Last7Days -DateProperty WhenChanged
Should -Invoke -CommandName Get-ADObject -Times 1 -Exactly -ParameterFilter {
$Filter -eq "(objectClass -eq 'groupPolicyContainer') -and (WhenChanged -ge `$DateFrom -and WhenChanged -le `$DateTo)"
}
}
}
}