One of the first things you should do when troubleshooting a problem like this is to enable DNS debug logging. �You've got a ton of different options to debug but in my case, I need more information regarding dynamic updates. �This is what my configuration looks like on one of my DNS servers.

DNSDebugLogSetting
DNS Debug Logging

When this is enabled, it will begin creating a log file at the file path you specify which looks like this:

DNSDebugLog
DNS Debug Log

The first row of marked out lines is the IP address and the last row is the DNS record it attempted to updated. �These were marked out for obvious reasons. �Depending on the options you choose this log file can become enormous and isn't in the easiest format to read. �What if I want to filter out just a single IP or narrow it down by a certain timeframe? �You can't do that with the default log file. �This is why I created a PowerShell summary script.

The script below takes this log file and parses it out into a nice CSV file that looks like this:

Output
PowerShellified DNS Debug Log

That looks a whole lot better, right? The script looks through the log file for any errors and parses out the date, IP and the error and places it into a nicely formatted CSV. It also excludes all of the DNS server IPs. For some reason, no matter which option you pick I found that the DNS server IPs themselves kept showing up. I just need to know the client IP address that's having a problem updating it's DNS record.

## The log file you specified in the debug logging dialog box
$DnsDebugLogFilePath = '\\DNSSERVER\c$\DnsDebugLog.log'
$OutputFilePath = 'C:\DNSDebugLogSummary.csv'
## Find all of the DNS server IPs in the current domain
$DnsServerIPs = ((Get-ADDomain).ReplicaDirectoryServers | Resolve-DnsName).IPAddress

## Find all lines in the log file that don't contain the strings 'NOERROR' or are blank.  This
## retrieves only the lines with errors in them.
Select-String -Pattern 'NOERROR|^\s*
 -Path $DnsDebugLogFilePath -NotMatch | foreach {
    try {
        ## Find lines containing an IP address
        if ($_.Line -match '\b(?:\d{1,3}\.){3}\d{1,3}\b') {
            $IP = $Matches[0]
            ## If the IP isn't a DNS server it must be a client IP
            if ($DnsServerIPs -notcontains $IP) {
                Write-Verbose "Processing IP '$IP'"
                $Split = $_.Line.Split(' ')
                $Date = $Split[0]
                $Time = $Split[1] + $Split[2]
                $Err = [regex]::Match($_.Line, '\[(.*)\]').Groups[1].Value
                [pscustomobject]@{ 'Date' = "$Date $Time"; 'IP' = $IP; 'Error' = $Err }
            }
        }
    } catch {
        Write-Warning $_.Exception.Message
    }
}| Export-Csv -Path $OutputFilePath -Append -NoTypeInformation

Join the Jar Tippers on Patreon

It takes a lot of time to write detailed blog posts like this one. In a single-income family, this blog is one way I depend on to keep the lights on. I'd be eternally grateful if you could become a Patreon patron today!

Become a Patron!