Which version of Access Analyzer do you have?
Access Analyzer 12.0
What is a one sentence summary of your feature request?
Improve GetSiteServers Function to account for a Site without Servers contrainer
Please describe your idea in detail. What is your problem, why do you feel this idea is the best solution, etc.
The GetSiteServers PowerShell function within the AD_DomainInfo Sites Query fails when a AD Site does not have a Servers container. While not having a Servers container is not normal and indicates a configuration issue with the Site, the function should be able to catch the error and continue. Current version of the GetSiteServers function fails and does not return any Sites when it runs into a site without Servers container.
Error without updated function:
Exception calling "SendRequest" with "1" argument(s): "The object does not exist."
At line:146 char:9
+ $response = [System.DirectoryServices.Protocols.SearchRespons ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
How do you currently solve the challenges you have by not having this feature?
Below is an update to the GetSiteServers function that will catch the error and output a Warning message letting administrators know there’s no Servers container on the specific Site.
function GetSiteServers([System.DirectoryServices.Protocols.LdapConnection]$ldapConnection, [string]$siteDn)
{
Write-Host "Retrieving site servers from '$siteDn'"
$searchRoot = "CN=Servers,$siteDn"
$searchRequest = New-Object 'System.DirectoryServices.Protocols.SearchRequest' @(
$searchRoot,
'(objectClass=server)',
[System.DirectoryServices.Protocols.SearchScope]::OneLevel,
[string[]] @('cn', 'distinguishedName', 'dNSHostName')
)
$searchRequest.SizeLimit = 0
$pagingControl = New-Object 'System.DirectoryServices.Protocols.PageResultRequestControl' @(1000)
[void]$searchRequest.Controls.Add($pagingControl)
$siteServerInfos = @()
do {
try {
$response = [System.DirectoryServices.Protocols.SearchResponse]$ldapConnection.SendRequest($searchRequest)
}
catch [System.DirectoryServices.Protocols.DirectoryOperationException] {
if ($_.Exception.Response.ResultCode -eq [System.DirectoryServices.Protocols.ResultCode]::NoSuchObject) {
Write-Warning "Site '$siteDn' does not have a CN=Servers container. Skipping."
return @()
}
throw
}
if ($response -eq $null) { break }
foreach ($entry_ in $response.Entries)
{
$entry = [System.DirectoryServices.Protocols.SearchResultEntry]$entry_
$cn = $entry.Attributes['cn'].GetValues([string])[0].ToString()
$dn = $entry.Attributes['distinguishedName'].GetValues([string])[0].ToString()
$dnsHostNameAttr = $entry.Attributes['dNSHostName']
if ($dnsHostNameAttr -eq $null)
{
Write-Warning "SiteServer '$dn' does not have a dNSHostName, skipping"
continue
}
$dnsHostName = $dnsHostNameAttr.GetValues([string])[0].ToString()
$dotPos = $dnsHostName.IndexOf('.')
if ($dotPos -eq -1) { continue }
$domainName = $dnsHostName.Substring($dotPos + 1)
$siteServerInfos += $(NewSiteServerInfo $cn $dnsHostName $domainName $dn)
}
foreach ($control in $response.Controls)
{
if ($control -is [System.DirectoryServices.Protocols.PageResultResponseControl])
{
$pageResponse = [System.DirectoryServices.Protocols.PageResultResponseControl]$control
$pagingControl.Cookie = $pageResponse.Cookie
break
}
}
} while ($pagingControl.Cookie.Length -ne 0)
return $siteServerInfos
}