Reviewing DNS logs with PowerShell

I recently helped out on a project where DNS services were being moved to different hosts with new IP addresses. After updating the DHCP scope options and static DNS configuration settings on all servers, the team turned on DNS logging to look for any hosts still using the old DNS servers. The logs contained a lot more records than originally anticipated, so I wrote the following code to help summarize the logs.

This first block of code found all of the DNS queries that didnt come from domain controllers, manipulated the log file entry to get just the source IP and stored all the results in a collection named myResults.

[cc lang=”powershell”]
# Create a pipe separated list of domain controllers
$listOfDCs = “||”
$loopbackIPv6 = [regex]::Escape(“::1”)

$myResults = @()
Get-Content e:\dnslogs\dns.log | ?{$_ -match ‘ PACKET ‘ -and $_ -match “UDP Rcv ” -and $_ -notmatch $listOfDCs -and $_ -notmatch $loopbackIPv6} | %{
$sourceIP = (($_ -split(“UDP Rcv “))[1] -split(” “))[0]
$myResults += New-Object psobject -Property @{
SourceIP = $sourceIP
FullLine = $_
} # end new object
} # end dns log loop

Once we rearranged the data so that it would be more usable, we wanted to find the source IP addresses responsible for the majority of the lookups. The idea here is that once you resolve the issue with these hosts, you can recreate the DNS log file and the next pass through will contain fewer entries and therefor run faster. Using powershell this is a pretty quick one liner after you run the block of code above.

[cc lang=”powershell”]
$myResults | Group-Object -Property SourceIP | Sort-Object Count -Descending

That is helpful, but the team really wanted to know host name. Using the data from host naming convention, they could tell what team would be responsible for resolution of the issue. With just a few more lines of code we can easily return that information too.
[cc lang=”powershell”]
# Since server guys are more likely to know host names than IP address, we will loop through the resutls and
# lookup the host name, then sort the list to find the largest number of lookups
$myResults | Group-Object -Property SourceIP | Sort-Object Count -Descending | %{
$sourceName = try { []::GetHostByAddress($_.Name).HostName } catch { “UNKNOWN” }
New-Object psobject -property @{
HostName = $sourceName
IP = $_.Name
Count = $_.Count

This entry was posted in Scripting. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *