Post

Monitoring DNS Changes with PowerShell - A Script Breakdown

Image

In today’s dynamic network environments, keeping track of DNS changes is crucial, especially when managing critical resources like load balancers or web servers. In this blog post, I’ll walk you through a PowerShell script designed to monitor changes in the IP addresses associated with a Fully Qualified Domain Name (FQDN). When a change is detected, the script sends an email alert, ensuring that you’re always in the loop.

Script Overview

This script queries the current DNS server for the IP addresses of a specified FQDN. It then compares the current IP addresses with the last known IPs stored in a file. If there’s a change, it sends an email notification and updates the stored IPs.

Let’s dive into the details.

Script Breakdown

Variables

1
2
3
4
5
6
$fqdn = "fqdn.example.com"
$emailTo = "[email protected]"
$emailFrom = "[email protected]"
$smtpServer = "smtp.example.com"
$smtpPort = 25
$ipFile = "last_known_ip.txt"
  • $fqdn: The FQDN for which we want to monitor IP changes.
  • $emailTo / $emailFrom: Email addresses for sending alerts.
  • $smtpServer / $smtpPort: SMTP server details for sending the email.
  • $ipFile: The file that stores the last known IP addresses.

Function to Query DNS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function Get-FQDNIPs {
    param ([string]$fqdn)

    Write-Host "Querying current DNS server for IPs of $fqdn"
    $output = nslookup $fqdn
    # Extract IP addresses from the nslookup output
    $ipAddresses = $output | Select-String -Pattern "Address:" | ForEach-Object {
        $_.Line.Split(":")[1].Trim()
    } | Where-Object {
        $_ -match "^\d{1,3}(\.\d{1,3}){3}$"
    }

    if ($ipAddresses.Count -gt 0) {
        Write-Host "IP addresses found: $($ipAddresses -join ', ')"
        return $ipAddresses
    } else {
        Write-Host "No IP addresses found for $fqdn"
        return $null
    }
}

This function uses the nslookup command to query the DNS server for the IP addresses of the given FQDN. It filters and returns valid IP addresses.

Main Script Logic

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$currentIPs = Get-FQDNIPs -fqdn $fqdn

if ($currentIPs) {
    $currentIPsString = $currentIPs -join ", "
    Write-Host "Current IP addresses for ${fqdn}: ${currentIPsString}"

    if (Test-Path $ipFile) {
        $lastKnownIPs = Get-Content $ipFile
        $lastKnownIPsString = $lastKnownIPs -join ", "
        Write-Host "Last known IP addresses for ${fqdn}: ${lastKnownIPsString}"

        if ($currentIPsString -ne $lastKnownIPsString) {
            Write-Host "IP addresses have changed. Sending email..."
            $body = "The IP addresses for ${fqdn} have changed from ${lastKnownIPsString} to ${currentIPsString}."
            Send-MailMessage -From $emailFrom -To $emailTo -Subject "IP Address Change Alert for ${fqdn}" -Body $body -SmtpServer $smtpServer -Port $smtpPort
            Set-Content $ipFile -Value $currentIPs
            Write-Host "Stored IP addresses updated to: ${currentIPsString}"
        } else {
            Write-Host "IP addresses have not changed. No email sent."
        }
    } else {
        Write-Host "No previous IP addresses found. Storing current IP addresses."
        Set-Content $ipFile -Value $currentIPs
    }
} else {
    Write-Host "Failed to resolve any IP addresses for ${fqdn}."
}
  • Current IP Query: The script starts by querying the current IP addresses using the Get-FQDNIPs function.
  • IP Comparison: It then checks if a file containing the last known IPs exists. If it does, it compares the current IPs with the previous ones.
  • Email Notification: If the IPs have changed, the script sends an email alert. It then updates the file with the new IPs.
  • Initial Setup: If the file doesn’t exist, the script creates it with the current IPs.

Practical Applications

This script is particularly useful in environments where DNS records for critical infrastructure may change, and immediate awareness of these changes is essential for maintaining system stability and performance. By automating the monitoring and notification process, this script saves time and reduces the risk of downtime due to unanticipated DNS changes.

Conclusion

PowerShell scripts like this one provide a straightforward yet powerful way to automate network monitoring tasks. By implementing this script, you can stay informed about crucial DNS changes and take prompt action when necessary.

Complete Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# Variables
$fqdn = "fqdn.example.com"
$emailTo = "[email protected]"
$emailFrom = "[email protected]"
$smtpServer = "smtp.example.com"
$smtpPort = 25
$ipFile = "last_known_ip.txt"

# Function to query the current host DNS server for the FQDN's IP addresses
function Get-FQDNIPs {
    param ([string]$fqdn)

    Write-Host "Querying current DNS server for IPs of $fqdn"
    $output = nslookup $fqdn

    # Extract all lines that start with 'Address:' but not 'Address: 127.0.0.1'
    $ipAddresses = $output | Select-String -Pattern "Address:" | ForEach-Object {
        $_.Line.Split(":")[1].Trim()
    } | Where-Object {
        $_ -match "^\d{1,3}(\.\d{1,3}){3}$"
    }

    if ($ipAddresses.Count -gt 0) {
        Write-Host "IP addresses found: $($ipAddresses -join ', ')"
        return $ipAddresses
    } else {
        Write-Host "No IP addresses found for $fqdn"
        return $null
    }
}

# Get the current IP addresses from the current host DNS server
$currentIPs = Get-FQDNIPs -fqdn $fqdn

if ($currentIPs) {
    # Convert IP addresses to a comma-separated string
    $currentIPsString = $currentIPs -join ", "
    Write-Host "Current IP addresses for ${fqdn}: ${currentIPsString}"

    # Check if a previous IP address file exists
    if (Test-Path $ipFile) {
        $lastKnownIPs = Get-Content $ipFile
        $lastKnownIPsString = $lastKnownIPs -join ", "
        Write-Host "Last known IP addresses for ${fqdn}: ${lastKnownIPsString}"

        if ($currentIPsString -ne $lastKnownIPsString) {
            Write-Host "IP addresses have changed. Sending email..."
            # IP addresses have changed, send an email
            $body = "The IP addresses for ${fqdn} have changed from ${lastKnownIPsString} to ${currentIPsString}."
            Write-Host "Email body: $body"

            Send-MailMessage -From $emailFrom -To $emailTo -Subject "IP Address Change Alert for ${fqdn}" -Body $body -SmtpServer $smtpServer -Port $smtpPort

            # Update the stored IP addresses
            Set-Content $ipFile -Value $currentIPs
            Write-Host "Stored IP addresses updated to: ${currentIPsString}"
        } else {
            Write-Host "IP addresses have not changed. No email sent."
        }
    } else {
        Write-Host "No previous IP addresses found. Storing current IP addresses."
        # No previous IP addresses recorded, store the current IPs
        Set-Content $ipFile -Value $currentIPs
    }
} else {
    Write-Host "Failed to resolve any IP addresses for ${fqdn}."
}

Happy scripting!

This post is licensed under CC BY 4.0 by the author.