Introduction to DNS Logging and Diagnostics on Windows Server 2019
DNS logging and diagnostics are essential for troubleshooting resolution failures, detecting security threats, meeting compliance requirements, and understanding traffic patterns on your network. Windows Server 2019 provides two distinct logging mechanisms for DNS: the Windows Event Log (structured event data, always on) and the DNS Debug Log (detailed packet-level tracing, optional and configurable). Understanding both and configuring them appropriately gives you comprehensive visibility into DNS operations.
DNS Event Log Channels
Windows Server 2019 DNS Server writes to three Windows Event Log channels:
DNS Server (classic): Found under Windows Logs > DNS Server. Contains operational events like zone load failures, service start/stop, and configuration changes. Event IDs in the 4000-4999 range.
Microsoft-Windows-DNS-Server/Audit: Found under Applications and Services Logs > Microsoft > Windows > DNS-Server > Audit. Contains security-relevant events like zone modifications, record changes, and DNSSEC operations.
Microsoft-Windows-DNS-Server/Analytical: High-volume per-query diagnostic channel. Disabled by default because it generates enormous volumes of events.
# View DNS Server classic event log
Get-WinEvent -LogName "DNS Server" -MaxEvents 50 |
Select-Object TimeCreated, Id, LevelDisplayName, Message | Format-List
# View DNS Audit log
Get-WinEvent -LogName "Microsoft-Windows-DNS-Server/Audit" -MaxEvents 50 |
Select-Object TimeCreated, Id, Message | Format-List
# List all DNS-related event logs
Get-WinEvent -ListLog "*DNS*" | Select-Object LogName, IsEnabled, RecordCount | Format-Table
Enable the DNS Analytical Log
The Analytical log captures every individual DNS query and response. Because of the volume, it should only be enabled temporarily during active troubleshooting and disabled afterwards. The log is stored in a circular .etl file.
# Enable the DNS Analytical log
$log = Get-WinEvent -ListLog "Microsoft-Windows-DNS-Server/Analytical"
$log.IsEnabled = $true
$log.SaveChanges()
# Verify it is enabled
Get-WinEvent -ListLog "Microsoft-Windows-DNS-Server/Analytical" |
Select-Object LogName, IsEnabled, MaximumSizeInBytes
# View analytical log events (may require -Oldest for high volume)
Get-WinEvent -LogName "Microsoft-Windows-DNS-Server/Analytical" -MaxEvents 100 |
Select-Object TimeCreated, Id, Message | Format-List
# Disable when done
$log = Get-WinEvent -ListLog "Microsoft-Windows-DNS-Server/Analytical"
$log.IsEnabled = $false
$log.SaveChanges()
Configure DNS Debug Logging
DNS Debug Logging (also called DNS diagnostic logging) writes raw packet-level DNS query and response data to a plain text log file. This is the most detailed logging option and is particularly useful for capturing exactly what queries and responses look like on the wire, including source IP, query name, record type, and whether the query was answered from cache or recursion.
# Enable all DNS diagnostic logging categories
Set-DnsServerDiagnostics `
-Queries $true `
-Answers $true `
-Send $true `
-Receive $true `
-UdpPackets $true `
-TcpPackets $true `
-FullPackets $true `
-SaveLogsToPersistentStorage $true `
-UseSystemEventLog $false `
-EnableLoggingToFile $true `
-LogFilePath "C:DNSdns.log" `
-MaxMBFileSize 500
# Create log directory if it doesn't exist
New-Item -ItemType Directory -Path "C:DNS" -Force
# Verify current diagnostics settings
Get-DnsServerDiagnostics | Format-List
The debug log at C:DNSdns.log contains entries in this format:
# Example debug log entry format:
# Date Time ThreadID Context PacketSize ClientIP Protocol PacketType QType QName Response
# 17/05/2026 14:23:01 0E44 PACKET 0000002C UDP Rcv 10.1.1.100 R Q [8081 A NOERROR] A (3)www(7)example(3)com
Selective Logging — Filter by IP or Query Type
To avoid logging every query on a busy server, enable filtering to capture only traffic from specific clients or for specific query types:
# Log only queries from a specific IP address
Set-DnsServerDiagnostics -FilterIPAddressList "10.1.1.100","10.1.1.101"
# Log only specific query types (bit flags)
# 1=A, 2=NS, 4=CNAME, 8=SOA, 16=PTR, 32=MX, 64=AAAA, 256=SRV, 32768=ALL
Set-DnsServerDiagnostics -FilterEventPackets 32768 # All types
DNS Audit Log — Zone Change Tracking
The Audit log is enabled by default and captures DNS record additions, deletions, and modifications. This is critical for detecting unauthorised DNS changes:
# Search audit log for record creation events (Event ID 513)
Get-WinEvent -LogName "Microsoft-Windows-DNS-Server/Audit" |
Where-Object Id -eq 513 |
Select-Object TimeCreated, Message | Format-List
# Search for record deletion (Event ID 514)
Get-WinEvent -LogName "Microsoft-Windows-DNS-Server/Audit" |
Where-Object Id -eq 514 |
Select-Object TimeCreated, Message | Format-List
# Zone modification events (ID 515-520)
Get-WinEvent -LogName "Microsoft-Windows-DNS-Server/Audit" |
Where-Object { $_.Id -ge 515 -and $_.Id -le 520 } |
Select-Object TimeCreated, Id, Message | Format-List
Configure Event Log Size and Retention
Increase the size of the DNS event logs to retain sufficient history for investigation:
# Set DNS Server classic log to 100MB, overwrite as needed
wevtutil sl "DNS Server" /ms:104857600 /rt:false
# Set DNS Audit log to 200MB
wevtutil sl "Microsoft-Windows-DNS-Server/Audit" /ms:209715200 /rt:false
# Confirm
wevtutil gl "Microsoft-Windows-DNS-Server/Audit" | Select-String -Pattern "maxSize|retention"
# Alternatively via PowerShell
$log = Get-WinEvent -ListLog "Microsoft-Windows-DNS-Server/Audit"
$log.MaximumSizeInBytes = 209715200
$log.LogMode = [System.Diagnostics.Eventing.Reader.EventLogMode]::Circular
$log.SaveChanges()
Automate DNS Log Analysis with PowerShell
Build a daily summary report of DNS activity:
# Summarise DNS errors from the last 24 hours
$since = (Get-Date).AddHours(-24)
$events = Get-WinEvent -LogName "DNS Server" -ErrorAction SilentlyContinue |
Where-Object { $_.TimeCreated -gt $since -and $_.Level -le 3 }
Write-Host "DNS Errors/Warnings in last 24h: $($events.Count)"
$events | Group-Object Id | Sort-Object Count -Descending |
Select-Object Name, Count | Format-Table
# Top 10 query types from debug log (parse text log)
if (Test-Path "C:DNSdns.log") {
Get-Content "C:DNSdns.log" |
Select-String " Q " |
ForEach-Object { ($_ -split "s+")[12] } |
Group-Object | Sort-Object Count -Descending |
Select-Object -First 10 Name, Count | Format-Table
}
Centralise DNS Logs with Windows Event Forwarding
Forward DNS audit events to a central Windows Event Collector for enterprise-scale monitoring:
# On the DNS server (event source), enable WinRM
winrm quickconfig -q
# Create a subscription on the collector server
# wecutil cs dns-audit-subscription.xml
# Where the XML file specifies the DNS-Server/Audit log and source computers
# Alternatively use a simplified command
wecutil qc /q # Quick configure event collector service
# Check subscriptions
wecutil es
DNS Performance Counters
Windows Server 2019 exposes DNS performance counters under the DNS performance object. Monitor these to understand load and cache health:
# List available DNS performance counters
Get-Counter -ListSet DNS | Select-Object -ExpandProperty Counter
# Capture DNS statistics snapshot
Get-Counter "DNSTotal Query Received/sec",
"DNSTotal Response Sent/sec",
"DNSRecursive Queries/sec",
"DNSCache Hits %",
"DNSCache Misses",
"DNSAXFR Request Received" -SampleInterval 5 -MaxSamples 3
Summary
Comprehensive DNS logging on Windows Server 2019 combines the always-on Audit log for change tracking, the optional Analytical and Debug logs for deep packet inspection during troubleshooting, and Windows performance counters for capacity planning. Configuring appropriate log sizes, enabling filter-based selective logging on busy servers, and automating log analysis with PowerShell provides the visibility needed for both operational troubleshooting and security monitoring without overwhelming storage or performance.