internal/functions/groupPolicy/Resolve-GPFilterMapping.ps1
function Resolve-GPFilterMapping { <# .SYNOPSIS Determines which filter conditions apply to which GPO .DESCRIPTION Determines which filter conditions apply to which GPO Used by components that apply rules based on GPOs, such as GP Permissions and GP Ownership. .PARAMETER Conditions The list of conditions that need to be evaluated. .PARAMETER Server The server / domain to work with. .PARAMETER Credential The credentials to use for this operation. .EXAMPLE PS C:\> Resolve-GPFilterMapping @parameters -Conditions ($ownerConfig.FilterConditions | Remove-PSFNull -Enumerate | Sort-Object -Unique) Returns a mapping of which of the conditions needed and what GPOs they apply to. #> [CmdletBinding()] param ( [AllowEmptyCollection()] [string[]] $Conditions, [PSFComputer] $Server, [PSCredential] $Credential ) process { $parameters = $PSBoundParameters | ConvertTo-PSFHashtable -Include Server, Credential $result = [PSCustomObject]@{ Success = $true Mapping = @{ } Conditions = $Conditions AllGpos = @() MissingCondition = $null ErrorType = 'None' ErrorData = @() ErrorTarget = $null } $allFilters = @{ } foreach ($filterObject in Get-DMGPPermissionFilter) { $allFilters[$filterObject.Name] = $filterObject } $result.MissingCondition = $Conditions | Where-Object { $_ -notin $allFilters.Keys } if ($result.MissingCondition) { $result.ErrorType = 'MissingCondition' $result.Success = $false $result return } if ($Conditions) { $relevantFilters = $allFilters | ConvertTo-PSFHashtable -Include $Conditions } else { $relevantFilters = @() } $allGpos = Get-ADObject @parameters -LDAPFilter '(objectCategory=groupPolicyContainer)' -Properties DisplayName $result.AllGpos = $allGpos $filterToGPOMapping = @{ } $managedGPONames = (Get-DMGroupPolicy).DisplayName | Resolve-String #region Process individual filter conditions :conditions foreach ($condition in $relevantFilters.Values) { switch ($condition.Type) { #region Managed - Do we define the policy using the GroupPolicy Component? 'Managed' { if ($condition.Reverse -xor (-not $condition.Managed)) { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -NotIn $managedGPONames } else { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -In $managedGPONames } } #endregion Managed - Do we define the policy using the GroupPolicy Component? #region Path - Resolve by where GPOs are linked 'Path' { $searchBase = Resolve-String -Text $condition.Path if (-not (Test-ADObject @parameters -Identity $searchBase)) { if ($condition.Optional) { Write-PSFMessage -String 'Resolve-GPFilterMapping.Filter.Path.DoesNotExist.SilentlyContinue' -StringValues $Condition.Name, $searchBase -Target $condition continue conditions } $result.Success = $false $result.ErrorType = 'PathNotFound' $result.ErrorData = $searchBase $result.ErrorTarget = $condition $result return } $objects = Get-ADObject @parameters -SearchBase $searchBase -SearchScope $condition.Scope -LDAPFilter '(|(objectCategory=OrganizationalUnit)(objectCategory=domainDNS))' -Properties gPLink $allLinkedGpoDNs = $objects | ConvertTo-GPLink | Select-Object -ExpandProperty DistinguishedName -Unique if ($condition.Reverse) { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DistinguishedName -NotIn $allLinkedGpoDNs } else { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DistinguishedName -In $allLinkedGpoDNs } } #endregion Path - Resolve by where GPOs are linked #region GPName - Match by name, using either direct comparison, wildcard or regex 'GPName' { $resolvedGpoName = Resolve-String -Text $condition.GPName switch ($condition.Mode) { 'Explicit' { if ($condition.Reverse) { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -NE $resolvedGpoName } else { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -EQ $resolvedGpoName } } 'Wildcard' { if ($condition.Reverse) { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -NotLike $resolvedGpoName } else { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -Like $resolvedGpoName } } 'Regex' { if ($condition.Reverse) { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -NotMatch $resolvedGpoName } else { $filterToGPOMapping[$condition.Name] = $allGpos | Where-Object DisplayName -Match $resolvedGpoName } } } } #endregion GPName - Match by name, using either direct comparison, wildcard or regex } } #endregion Process individual filter conditions $result.Mapping = $filterToGPOMapping $result } } |