Oft overlooked parts of Active Directory is Sites and Services. If it isn’t overlooked, it can be effectively ignore or it’s misunderstood. Over the nineteen (almost twenty!) years that Active Directory has been out in the wild, this author has seen some common problems or misconfigurations with AD Sites and Services. As such there are a few things that he uses PowerShell to analyze for best practices. Take these recommendations with a grain of salt as like most recommendation, they do not apply to all environments.
Missing Subnets
Undefined subnets can cause clients to log into the wrong AD site. This can lead to potential login slowness and other issues. As such if these missing subnets can be identify and added to the correct site, it could improve your end user’s experience. In order to find out where these errant logins are coming from, we need to analyze the NETLOGON.Log file on each Domain Controller. Can we use PowerShell to do that?
A script I found in the past has been my go to for the past 5 years or so. The script was created by Jeremy Saunders from J House Consulting – http://www.jhouseconsulting.com/ – and his script is listed here – http://www.jhouseconsulting.com/2014/01/21/script-to-find-missing-subnets-in-active-directory-1127.
The output from the script will be put in an Output folder and the subnet that is missing will be listed. Make sure to add these missing subnets to your Sites and Services.
Empty Sites
An empty site is generally not recommended. The term describes a site without any Domain Controllers. A site of this sort has two possible reasons for existing – Microsoft SCCM product used for software distribution and other management tools to help identify something in Active directory for end users or application use. In general this isn’t an issue, but if they are not needed, removing them is a good practice. Less for Active directory to replicated to existing Domain Controllers in other sites.
How do we find those empty sites?
[sourcecode language=”powershell”]
# Empty Site Check
$SiteNames = (Get-ADReplicationSite -Filter *).Name
Foreach ($Site in $SiteNames) {
If ( (Get-ADDomainController -Filter {Site -eq $Site}).Count -eq 0) {
Write-host 'Empty Site Found – ' -ForegroundColor White -NoNewline
Write-Host "$Site" -ForegroundColor Yellow -NoNewline
Write-Host ' – is this site needed?' -ForegroundColor White
$Row = "Enpty site found – $Site – Is this site needed?" | Out-File $Destination -Append
}
}
[/sourcecode]
Manual Links Now, this one is one that gets configured a lot, so a quick review. When a new Active Directory domain and forest are created and multiple sites are created, Active Directory (the KCC process specifically) creates links for replication between all sites. It does this automatically and can also be a dynamic process if changes are needed. these links are replaced with manual links for two reasons – to control replication manually (determine which DCs replicate to which DCs and Site models like hub and spoke) or the links are changed because of an Active Directory replication issue. Neither of these are recommended. If a link needs to be created to fix an issue, there is something larger going on and that should be fixed first. How do we determine if these links exit programatically?
[sourcecode language=”powershell”]
$DomainControllers = (Get-ADDomainController -Filter *).Name
Foreach ($DomainController in $DomainControllers) {
$Links = Get-ADReplicationConnection -Server $DomainController
$AutoGenerated = $Links.AutoGenerated
If ($AutoGenerated -like '*False*') {
Write-Host 'Manual link detected'
}
}
[/sourcecode]
Replication Mess
Last but not least is querying for a list of all the replication links that exist for each domain controller. This can also be provided via a PowerShell query. One reason this should be looked at is to see the overall links for each Domain Controller. We can review the point to point link, the type of lnk (automatic or manual) and more. At the very least, this can be used for documentation. At the most, it could be used for planning for the future on how to improve the layout of the AD Replication Links.
[sourcecode language=”powershell”]
$DomainControllers = (Get-ADDomainController -Filter *).Name
Foreach ($DomainController in $DomainControllers) {
# Set up variables for the loop:
$Query = $True $AutoGenerated = $Null
# Get a list of links for this Domain Controller:
Try {
$Links = Get-ADReplicationConnection -Server $DomainController -ErrorAction STOP
} Catch {
Write-host 'Failed – Unable to query links.' -ForegroundColor Red
$Query = $False
}
# Check each set of links to analyze the ones for each Domain Controller:
If ($Query) {
Foreach ($Line in $Links) {
# Fix Values
$Name = $Line.Name
$Autogenerated= $Line.Autogenerated
$ReplicateFromDirectoryServer = $Line.ReplicateFromDirectoryServer
$ReplicateToDirectoryServer = $Line.ReplicateToDirectoryServer
$FromLarge = $ReplicateFromDirectoryServer.Split(',')[1]
$ToLarge = $ReplicateToDirectoryServer.Split(',')[0]
$FinalFrom = $FromLarge.Split('=')[1]
$FinalTo = $ToLarge.Split('=')[1]
$SiteLarge = $Line.DistinguishedName.Split(',')[4]
$Site = $SiteLarge.Split('=')[1]
$Row = "$DomainController,$Site,$Name,$Autogenerated,$FinalFrom,$FinalTo" | Out-File $ADReplicationConnectionDestination -Append
}
} Else {
Write-host ' Domain Controller with no Links found – ' -ForegroundColor White -NoNewline
Write-Host "$DomainController" -ForegroundColor Yellow -NoNewline
Write-Host ' – is this Domain Controller needed?' -ForegroundColor White
$Row = "$DomainController,NoLink,,,," | Out-File $ADReplicationConnectionDestination -Append
}
}
[/sourcecode]
Now we have a set of code we can use to start checking the health of an Active Directory environment. There are far more items and settings to check, but this is a good place to begin with a health check.