In partnership with

THE PROBLEM

DNS is the backbone of your entire network. When it fails, users can't reach servers, applications can't communicate, and authentication breaks down completely. Most teams only discover DNS issues when everything stops working at once. This week we build a script that monitors your DNS servers around the clock and emails you the moment something fails — before your users notice.

THE SCRIPT

Save the script below to:

C:\Scripts\DNSHealthMonitor.ps1

powershell

# DNS Health Monitor
# Automate & Operate — automateandoperate.com

# Settings — update these
$from = "[email protected]"
$to = "[email protected]"
$smtpServer = "your.smtp.server"
$smtpPort = 587
$username = "[email protected]"
$password = ConvertTo-SecureString "yourpassword" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential($username, $password)
$logFile = "C:\Logs\DNSHealthMonitor.log"

# DNS servers to monitor
$dnsServers = @(
    "192.168.1.1",
    "192.168.1.2",
    "8.8.8.8"
)

# Test records to resolve — use known reliable hostnames
$testRecords = @(
    "google.com",
    "microsoft.com",
    "yourinternaldomain.local"
)

# Response time threshold in milliseconds
$responseTimeThreshold = 500

# Create log folder if missing
if (-not (Test-Path "C:\Logs")) {
    New-Item -ItemType Directory -Path "C:\Logs"
}

$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$report = @()
$failedServers = @()

foreach ($dnsServer in $dnsServers) {
    foreach ($record in $testRecords) {
        try {
            $startTime = Get-Date
            $result = Resolve-DnsName -Name $record -Server $dnsServer -ErrorAction Stop
            $responseTime = [math]::Round(((Get-Date) - $startTime).TotalMilliseconds, 0)

            $status = if ($responseTime -gt $responseTimeThreshold) {
                "SLOW"
            } else {
                "OK"
            }

            $report += [PSCustomObject]@{
                DNSServer    = $dnsServer
                TestRecord   = $record
                ResolvedIP   = ($result | Select-Object -First 1).IPAddress
                ResponseTime = "$responseTime ms"
                Status       = $status
            }

            Add-Content -Path $logFile -Value "$timestamp$dnsServer$record${responseTime}ms — $status"

        } catch {
            $report += [PSCustomObject]@{
                DNSServer    = $dnsServer
                TestRecord   = $record
                ResolvedIP   = "FAILED"
                ResponseTime = "N/A"
                Status       = "FAILED"
            }

            if ($failedServers -notcontains $dnsServer) {
                $failedServers += $dnsServer
            }

            Add-Content -Path $logFile -Value "$timestamp$dnsServer$record — FAILED — $_"
        }
    }
}

# Build email body
$emailBody = "DNS Health Monitor Report — $timestamp`n"
$emailBody += "Servers checked: $($dnsServers -join ', ')`n"
$emailBody += "Test records used: $($testRecords -join ', ')`n"
$emailBody += "Response time threshold: $responseTimeThreshold ms`n`n"
$emailBody += "RESULTS:`n"
$emailBody += "=" * 60 + "`n`n"

foreach ($entry in $report) {
    $emailBody += "DNS Server:    $($entry.DNSServer)`n"
    $emailBody += "Test Record:   $($entry.TestRecord)`n"
    $emailBody += "Resolved IP:   $($entry.ResolvedIP)`n"
    $emailBody += "Response Time: $($entry.ResponseTime)`n"
    $emailBody += "Status:        $($entry.Status)`n"
    $emailBody += "-" * 40 + "`n"
}

if ($failedServers.Count -gt 0) {
    $emailBody += "`nFAILED DNS SERVERS — ACTION REQUIRED:`n"
    $failedServers | ForEach-Object { $emailBody += "  !! $_`n" }
}

$emailBody += "`nAutomate & Operate — automateandoperate.com"

# Set subject based on results
$subject = if ($failedServers.Count -gt 0) {
    "DNS ALERT: $($failedServers.Count) DNS server(s) failing on $env:COMPUTERNAME"
} else {
    "DNS Health Report — All servers responding normally"
}

Send-MailMessage `
    -From $from -To $to `
    -Subject $subject `
    -Body $emailBody `
    -SmtpServer $smtpServer -Port $smtpPort `
    -UseSsl -Credential $credential

Update these lines:

  • $from / $to / $username / $password — your email details

  • $smtpServer — your SMTP server (e.g. smtp.office365.com)

  • $dnsServers — replace with your actual DNS server IP addresses

  • $testRecords — add your internal domain names to test internal resolution

  • $responseTimeThreshold — adjust if your network has higher acceptable latency

SETTING UP TASK SCHEDULER

  1. Press Windows key → type Task Scheduler → open it

  2. Click "Create Basic Task" → name it DNS Health Monitor

  3. Trigger: Daily → today → 6:00am → click Next

  4. Action: Start a program → click Next

  5. Program: powershell.exe

  6. Arguments:

-ExecutionPolicy Bypass -File "C:\Scripts\DNSHealthMonitor.ps1"
  1. Click Next → Finish

Set it to repeat every 30 minutes:

  1. Right click DNS Health MonitorProperties

  2. Click Triggers tab → Edit

  3. Check "Repeat task every" → set to 30 minutes

  4. Duration: Indefinitely

  5. Click OK → OK

TEST IT

Open PowerShell as administrator and run:

powershell

powershell.exe -ExecutionPolicy Bypass -File "C:\Scripts\DNSHealthMonitor.ps1"

To force a failure alert for testing, add a fake DNS server IP to the $dnsServers list such as 10.255.255.254 — it will fail to resolve and trigger an alert email immediately.

Check C:\Logs\DNSHealthMonitor.log to confirm all servers and records are being tested correctly.

WHY THIS MATTERS

DNS failures are invisible until they're catastrophic. A secondary DNS server can fail silently for weeks while your primary handles everything — until the primary also fails and your entire network goes dark. This script validates every DNS server independently every 30 minutes and gives you response time metrics so you can spot degradation before it becomes an outage.

THIS WEEK'S ACTION

Add your primary and secondary DNS server IPs to the $dnsServers list and run this today. Add at least one internal domain name to $testRecords to validate internal DNS resolution. Let it run for 48 hours and check the log — you'll have a full picture of your DNS health by Friday.

Reply to this email if you hit any issues — I read every reply.

Automate & Operate — automateandoperate.com

Speak naturally. Send without fixing.

Wispr Flow turns your voice into clean, professional text you can send the moment you stop talking. Not rough transcription you have to clean up. Actual polished text — ready for email, Slack, or any app.

Speak the way you think. Go on tangents. Change your mind mid-sentence. Flow strips the filler, fixes the grammar, and gives you text that reads like you spent five minutes writing it.

89% of messages sent with zero edits. Millions of professionals use Flow daily, including teams at OpenAI, Vercel, and Clay. Works on Mac, Windows, and iPhone.

Your AI budget tripled. See real usage patterns with Harmonic.

AI spend is now a major P&L line item—but most teams can't show what it's producing.

Harmonic Security maps AI activity to use cases and teams, revealing real productivity, shelfware, data risk, and adoption trends across approved and unapproved tools.

Give your board the data behind the return.

Keep Reading