One of the easiest things in Active Directory to get right (and one of the most neglected, in my experience) is ensuring that you have all of your subnets mapped to appropriate Active Directory Sites.
There’s a common error in the Windows Event Log (5807) that alerts you when a Domain Controller is being hit with requests from clients without a correct subnet/site mapping:
2,325… that’s a lot of connections without the correct subnet/site mapping.
To find out the IP addresses (and therefor subnets) of these machines, you need to look in the c:\windows\debug\netlogon.log file (on your Domain Controller) for lines with the error NO_CLIENT_SITE.
And because these errors are Domain Controller specific, you need to do this on every domain controller you have.
The script below will find all of your domain controllers, and extracts the last 24 hours worth of log entries from netlogon.log and compiles a single list of IP addresses that do not have subnet/site mappings. From there, you should be able to quickly whittle it down to subnets to add into Active Directory Sites and Services.
I limited the results to the last 24 hours, as there will always be old entries in the log files, and I only wanted what was new/current.
In my example event log entry (above), the 2,325 connections were actually only from 207 different IP addresses (found via the output of this script), which I then filtered down to 12 subnets – so
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# Set date format to match log file dates $today = (get-date).tostring("MM/dd"); # Get all Domain Controllers $domaindn = (get-addomain).distinguishedname; $dclocation = "OU=Domain Controllers," + $domaindn; $dcs = get-adcomputer -filter {enabled -eq $true} -searchbase $dclocation -properties lastlogondate | where {$_.lastlogondate -gt (get-date).adddays(-90)}; $nositeips = @(); # Loop through each Domain Controller found foreach ($dc in $dcs) { $filename = "\\" + $dc.dnshostname + "\c$\windows\debug\netlogon.log"; # Check that file has been writeen to in the last 24 hours $recentlymodified = ((get-childitem $filename).lastwritetime -gt (get-date).adddays(-1)) if ($recentlymodified) { # Get the log file from the DC $netlogonfile = get-content ($filename); # Start at the bottom of the log file, line number -1 $linecount = -1; # Get the details from the last line of the log file $logline = $netlogonfile[$linecount]; $loglinedate = [string](-split $logline)[0]; # Loop through the file, line by line, until the date does not match today while ($loglinedate -eq $today) { # If a "NO CLIENT SITE" error is found if ($logline -like "*NO_CLIENT_SITE*") { $nositeips = $nositeips + (-split $logline)[-1].trim(); } # Check the date on the next (previous) line $linecount--; $logline = $netlogonfile[$linecount]; $loglinedate = [string](-split $logline)[0]; } } } # Reduce found IP addresses down to unique entries $nositeips = $nositeips | select -unique | sort; # Display to screen $nositeips; |
The output looks like this:
You could always run this via scheduled task every 24 hours and fire-off an email with the list of IP addresses for action (that’s what I would do), to make sure you’re always on top of it.