Sometimes the noisiest one is the NETLOGON service because whenever a machine which either forgot its password or has a broken secure channel or doesn't have an account in AD tries to connect to a DC, Netlogon service throws and error to the System log. Don't ask me why it's an error, in my view it should be a warning (tops) as it's not really an error of NETLOGON. Moreover, if I was MSFT, I would have made it an optional event turned on/off via registry, similar to the NTDS diagnostics events under HKLM\SYSTEM\CurrentControlSet\services\NTDS\Diagnostics.
Anyway, let's not dwell on it but try to do something about it. If you are a conscientious AD guy (and why wouldn't you be, we all are conscientious when it's about work ;) ) you want to make things right. First step: let's identify the machines which have broken secure channel. It shouldn't be difficult, the machine name is part of the event message. However, I have 100+ domain controllers, 30+ sites, reading through the eventlog on a regular basis is not an option. Need a script!
The script which you'll see at the bottom of the article is capable of:
- Enumerating the netlogon events from a DC and parse the error message and the client name from the event description
- Can work against 1 DC or a list of DCs in a specified site
Some interesting facts about the script. It uses Get-WinEvent command. If you use it remotely, it can be quite slow, e.g. let's list all events with EventID 5805 from the System Event log:
Get-WinEvent -ea SilentlyContinue -ComputerName c3poDC -LogName System | where{$_.id -eq 5805}
It takes a bit more than 30 seconds:
Obviously, the biggest issue is that it takes all events and then filters to the eventid afterwards. Let's try a trick, hash table. It's in the help of the command that it takes filters in hash table format. Excellent, let's try this then:
Get-WinEvent -ea SilentlyContinue -ComputerName c3poDC -FilterHashtable @{LogName = "System"; id=5805}
Hmmm... not bad, 4 seconds, now we are talking.
We can just dress up the script a bit:
- take an integer which determines how many days we want to go back in the log (makes the query even quicker):
$after = (Get-Date).adddays(-$lastday)
Get-WinEvent -ea SilentlyContinue -ComputerName $srv -FilterHashtable @{LogName = "System"; StartTime = $after; id=5805} - take DC name which we want to query
- take site name, enumerate the DCs in the site, and then run through them:
$dclist = Get-ADDomainController -filter * | where{$_.site -ieq $site} | %{$_.name}
- parse the client name from the event message
$obj.Computer = [regex]::Match($_.message, "\d|\w+ failed").Value -ireplace " failed",""
- make sure we only pick up a client name only once, so we have a unique list of clients with secure channel issues at the end:
if($computerList -inotcontains $obj.Computer){
param( [string] $dcname = "",
[string] $site = "",
[int] $lastday = 2)
# if -dcname is not specified, but -site is, let's get the ist of DCs from that site
if(!$dcname -and $site){
Import-Module activedirectory
$dclist = Get-ADDomainController -filter * | where{$_.site -ieq $site} | %{$_.name}
}
else{
$dclist = @($dcname)
}
$dclist
# generate the start date for the eventlog query
$after = (Get-Date).adddays(-$lastday)
$objColl = $computerList = @()
if($dclist.length -gt 0){
foreach($srv in $dclist){
# get the netlogon 5805 events from the eventlog generated after the given date
Get-WinEvent -ea SilentlyContinue -ComputerName $srv -FilterHashtable @{LogName = "System"; StartTime = $after; id=5805} | %{
$obj = "" | select DC,Computer,message,Date
$obj.DC = $srv
# parse the computername from the event message
$obj.Computer = [regex]::Match($_.message, "\d|\w+ failed").Value -ireplace " failed",""
# if we haven't recorded the alert about the given computerm then record it
if($computerList -inotcontains $obj.Computer){
$obj.message = $_.message.Split("`n")[1]
$obj.Date = $_.TimeCreated
# add the computername to an array where we can check if we have picked up an event on the given computer already
$computerList += $obj.Computer
$objColl += $obj
}
}
}
}
else{
Write-Host -ForegroundColor "red" "No DC or Site specified."
}
$objColl