Created
August 15, 2025 21:54
-
-
Save jschell/a5111610342c95d41289f94e3a568046 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| function Get-DSLDAPQueryPolicy { | |
| <# | |
| .Synopsis | |
| Get LDAP query policy for the configuration naming context provided. | |
| .Description | |
| When LDAP query policy is applied, precendence is given to settings applied to a specific domain controller, next to settings applied to a site, finally the global defaults. | |
| .Parameter ConfigNCInput | |
| Specifies the Configuration Naming Context to use. By default, uses the current configuration naming context. | |
| .Example | |
| PS > Get-DSLDAPQueryPolicy | |
| Scope : Default | |
| Target : Global | |
| MaxQueryDuration : 120 | |
| MaxResultSetSize : 10000 | |
| MaxPoolThreads : 6 | |
| MaxNotificationPerConn : 50 | |
| MaxDatagramRecv : 1024 | |
| MaxTempTableSize : 10000 | |
| MaxPageSize : 1000 | |
| MaxConnIdleTime : 900 | |
| InitRecvTimeout : 120 | |
| MaxConnections : 5000 | |
| Description | |
| ----------- | |
| Returns the policy values for (in this example) the default scope. | |
| .Notes | |
| #### Name: Get-DSLDAPQueryPolicy | |
| #### Author: J Schell | |
| #### Version: 0.1.1 | |
| #### License: MIT License | |
| ### ChangeLog | |
| #### 2016-09-30::0.1.1 | |
| - parameratize, move into begin/ process sections | |
| #### 2016-09-29::0.1.0 | |
| - initial creation | |
| #> | |
| [CmdletBinding()] | |
| Param( | |
| $ConfigNCInput = ([adsi]"LDAP://RootDSE").configurationNamingContext | |
| ) | |
| Begin{ | |
| $configurationNamingContext = $configNCInput | |
| $dcNCResults = $null | |
| $dcWithNTDSQuerySetting = 0 | |
| $siteWithNTDSQuerySetting = 0 | |
| $sitesWithDC = @() | |
| $sitesWithDCNtds = @() | |
| $allPolicyFound = @() | |
| } | |
| Process{ | |
| $configNC = [adsi]"LDAP://$($configurationNamingContext)" | |
| $dcSearch = New-Object System.DirectoryServices.DirectorySearcher | |
| $dcSearch.SearchRoot = $configNC | |
| $dcSearch.filter = "(objectClass=nTDSDSA)" | |
| $dcSearch.searchScope = "subtree" | |
| $dcNCResults = $dcSearch.findAll() | |
| $configNC.Dispose() | |
| $dcSearch.Dispose() | |
| $forestDCFound = $dcNCResults.count | |
| Write-Verbose "Found `'$($forestDCFound)`' DCs in the forest" | |
| $dcNCResults | foreach { | |
| $ntdsSettingsDC = [adsi]$_.path | |
| if( $ntdsSettingsDC.queryPolicyObject ){ | |
| $dcWithNTDSQuerySetting++ | |
| $dcName = $($ntdsSettingsDC.Parent).Split(',')[0].Split('=')[1] | |
| $dcSpecificPolicy = New-Object -TypeName PsObject -Property ([ordered]@{ | |
| Scope = "Machine" | |
| Target = $dcName | |
| }) | |
| foreach($limit in $($ntdsSettingsDC.queryPolicyObject) ){ | |
| $keyValue = @( $limit.Split('=') ) | |
| $dcSpecificPolicy | Add-Member -MemberType NoteProperty -Name $keyValue[0] -Value $keyValue[1] | |
| } | |
| $allPolicyFound += @( $dcSpecificPolicy ) | |
| } | |
| $dcNC = $($ntdsSettingsDC.parent).split('//')[2] | |
| #strip the 'ldap://' prefix | |
| $siteFound = $dcNC.Split(',')[2..100] -join ',' | |
| # remove serverName cn, servers cn to get siteName | |
| $sitesWithDC += @( $siteFound ) | |
| $ntdsSettingsDC.Dispose() | |
| } | |
| Write-Verbose "Found `'$($dcWithNTDSQuerySetting)`' DCs with non-blank query policy settings" | |
| $sitesWithDC = $sitesWithDC | Select-Object -Unique | Sort-Object | |
| $uniqueSiteCount = $sitesWithDC.Count | |
| Write-Verbose "Found `'$($uniqueSiteCount)`' unique sites." | |
| $sitesWithDC | foreach { | |
| $dnSiteNTDS = "CN=NTDS Site Settings,$($_)" | |
| $sitesWithDCNtds += @( $dnSiteNTDS ) | |
| $adsiSiteNTDS = [adsi]"LDAP://$($dnSiteNTDS)" | |
| if( $adsiSiteNTDS.queryPolicyObject ){ | |
| $siteWithNTDSQuerySetting++ | |
| "$($adsiSiteNTDS.queryPolicyObject), $($adsiSiteNTDS.Parent)" | |
| $siteName = $($adsiSiteNTDS.Parent).Split(',')[0].Split('=')[1] | |
| $siteSpecificPolicy = New-Object -TypeName PsObject -Property ([ordered]@{ | |
| Scope = "Site" | |
| Target = $siteName | |
| }) | |
| foreach($limit in $($adsiSiteNTDS.queryPolicyObject) ){ | |
| $keyValue = @( $limit.Split('=') ) | |
| $siteSpecificPolicy | Add-Member -MemberType NoteProperty -Name $keyValue[0] -Value $keyValue[1] | |
| } | |
| $allPolicyFound += @( $siteSpecificPolicy ) | |
| } | |
| $adsiSiteNTDS.Dispose() | |
| } | |
| Write-Verbose "Found `'$($siteWithNTDSQuerySetting)`' Sites with non-blank query policy settings" | |
| $defaultQueryPolicyString = "CN=Default Query Policy,CN=Query-Policies,CN=Directory Service,CN=Windows NT,CN=Services,$($configurationNamingContext)" | |
| $defaultQueryPolicy = [ADSI]"LDAP://$($defaultQueryPolicyString)" | |
| $defaultQueryLimits = $defaultQueryPolicy.lDAPAdminLimits | |
| $defaultQueryPolicy.Dispose() | |
| $defaultPolicy = New-Object -TypeName PsObject -Property ([ordered]@{ | |
| Scope = "Default" | |
| Target = "Global" | |
| }) | |
| foreach ($limit in $defaultQueryLimits){ | |
| $keyValue = @( $limit.Split('=') ) | |
| $defaultPolicy | Add-Member -MemberType NoteProperty -Name $keyValue[0] -Value $keyValue[1] | |
| } | |
| $allPolicyFound += @( $defaultPolicy ) | |
| return $allPolicyFound | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment