This commit is contained in:
Przemyslaw Klys
2020-12-27 22:38:31 +01:00
parent f0d24e1902
commit c987ca9863
+135
View File
@@ -0,0 +1,135 @@
function Get-GPOZaurrLinkInheritance {
[cmdletbinding(DefaultParameterSetName = 'All')]
param(
[parameter(ParameterSetName = 'ADObject', ValueFromPipeline, ValueFromPipelineByPropertyName, Mandatory)][Microsoft.ActiveDirectory.Management.ADObject[]] $ADObject,
# weirdly enough site doesn't really work this way unless you give it 'CN=Configuration,DC=ad,DC=evotec,DC=xyz' as SearchBase
[parameter(ParameterSetName = 'Filter')][string] $Filter = "(objectClass -eq 'organizationalUnit' -or objectClass -eq 'domainDNS' -or objectClass -eq 'site')",
[parameter(ParameterSetName = 'Filter')][string] $SearchBase,
[parameter(ParameterSetName = 'Filter')][Microsoft.ActiveDirectory.Management.ADSearchScope] $SearchScope,
[parameter(ParameterSetName = 'Linked', Mandatory)][validateset('Root', 'DomainControllers', 'Other')][string[]] $Linked,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[switch] $Limited,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[switch] $SkipDuplicates,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[System.Collections.IDictionary] $GPOCache,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('ForestName')][string] $Forest,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[string[]] $ExcludeDomains,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[alias('Domain', 'Domains')][string[]] $IncludeDomains,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[System.Collections.IDictionary] $ExtendedForestInformation,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[switch] $AsHashTable,
[parameter(ParameterSetName = 'Filter')]
[parameter(ParameterSetName = 'ADObject')]
[parameter(ParameterSetName = 'Linked')]
[switch] $Summary
)
Begin {
$CacheReturnedGPOs = [ordered] @{}
$ForestInformation = Get-WinADForestDetails -Extended -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExtendedForestInformation $ExtendedForestInformation
if (-not $GPOCache -and -not $Limited) {
$GPOCache = @{ }
# While initially we used $ForestInformation.Domains but the thing is GPOs can be linked to other domains so we need to get them all so we can use cache of it later on even if we're processing just one domain
# That's why we use $ForestInformation.Forest.Domains instead
foreach ($Domain in $ForestInformation.Forest.Domains) {
$QueryServer = $ForestInformation['QueryServers'][$Domain]['HostName'][0]
Get-GPO -All -DomainName $Domain -Server $QueryServer | ForEach-Object {
$GPOCache["$Domain$($_.ID.Guid)"] = $_
}
}
}
}
Process {
if (-not $Filter -and -not $Linked) {
# We choose ALL
#$Linked = 'Root', 'DomainControllers', 'Site', 'Other'
}
$getGPOPrivInheritanceLoopSplat = @{
Linked = $Linked
ForestInformation = $ForestInformation
CacheReturnedGPOs = $CacheReturnedGPOs
SearchScope = $SearchScope
SearchBase = $SearchBase
ADObject = $ADObject
Filter = $Filter
}
Remove-EmptyValue -Hashtable $getGPOPrivInheritanceLoopSplat -Recursive
# we need to use nested functions to support pipeline output and as hashtable and reporting that returns single value
if ($AsHashTable -or $Summary) {
$HashTable = [ordered] @{}
$SummaryHashtable = [ordered] @{}
$Links = Get-GPOPrivInheritanceLoop @getGPOPrivInheritanceLoopSplat
foreach ($Link in $Links) {
$Key = -join ($Link.DomainName, $Link.GUID)
if (-not $HashTable[$Key]) {
$HashTable[$Key] = [System.Collections.Generic.List[PSCustomObject]]::new()
}
$HashTable[$Key].Add($Link)
}
foreach ($Key in $HashTable.Keys) {
[Array] $Link = $HashTable[$Key]
$EnabledLinks = $Link.Enabled.Where( { $_ -eq $true }, 'split')
if ($EnabledLinks[0].Count -gt 0) {
$IsLinked = $true
} else {
$IsLinked = $false
}
$SummaryLink = [PSCustomObject] @{
DisplayName = $Link[0].DisplayName
DomainName = $Link[0].DomainName
GUID = $Link[0].GUID
Linked = $IsLinked
LinksCount = $Link.Count
LinksEnabledCount = $EnabledLinks[0].Count
LinksDisabledCount = $EnabledLinks[1].Count
Links = $Link.Target
LinksObjects = $Link
}
$SummaryHashtable[$Key] = $SummaryLink
}
if ($AsHashTable -and $Summary) {
$SummaryHashtable
} elseif ($AsHashTable) {
$HashTable
} elseif ($Summary) {
$SummaryHashtable.Values
}
} else {
Get-GPOPrivInheritanceLoop @getGPOPrivInheritanceLoopSplat
}
}
End {
}
}