Powershell : SMTP Server Monitoring System

Email infrastructure is critical for business operations, yet many organizations lack proper monitoring tools to ensure their SMTP servers are functioning correctly. In this blog post, we'll explore how to build a comprehensive SMTP server monitoring system using PowerShell scripts that not only checks connectivity but also provides a professional dashboard for tracking server health over time.

The Requirements

Our client needed a monitoring solution for their SMTP servers with the following requirements:

  1. Check connectivity to specific SMTP servers on standard ports (25, 587)
  2. Verify DNS configuration (MX and SPF records)
  3. Log all check results for historical reference
  4. Present the data in a professional, easy-to-read dashboard
  5. Track changes in DNS configuration over time
  6. Run as a lightweight solution without complex dependencies
The Results

This is how the dashboard looks, you have the variable information and the current SPF record at the top with the latest status of the checks of the check for TCP:25 and TCP:587, then you move on to the checks with a "timeline" style view in chronological order.


You can also open any one of those checks to see the full details:


Then at the bottom of the website you will get any changes to the MX to SPF record shown in a audit style log:


When the website generation script is run you will get verbose output on the status, here you can see it has checked the JSON file for any changes and none were found:


Solution Overview

I developed a two-part solution:

  1. SMTP Server Check Script: A PowerShell script that tests server connectivity and DNS configuration, logging results to a file
  2. Dashboard Generator Script: A second script that processes the logs and creates a professional HTML dashboard

Let's examine each component and how it fulfills the requirements.

The SMTP Server Check Script

The first script focuses on performing the checks and logging the results. Here's how it addresses key requirements:

1. Server and Port Connectivity Testing

# Test basic TCP connectivity
function Test-TcpConnection {
    param (
        [string]$Server,
        [int]$Port,
        [int]$TimeoutMilliseconds = 5000
    )
    
    # ... connection logic ...
    
    # Measure response time
    $stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
    $connectionSuccess = $connectionTask.AsyncWaitHandle.WaitOne($TimeoutMilliseconds, $false)
    $stopwatch.Stop()
    $result.ResponseTime = $stopwatch.ElapsedMilliseconds
    
    # ... return result ...
}

This function:

  • Tests TCP connectivity to the server on specified ports
  • Measures response time in milliseconds
  • Handles connection timeouts gracefully
  • Returns detailed status information

2. DNS Configuration Verification

# Check MX records using nslookup command
function Get-MxRecordsNslookup {
    param ([string]$Domain)
    
    Write-Log "Checking MX records for $Domain using nslookup..."
    $output = nslookup -q=mx $Domain 2>&1
    # ... log output ...
}

# Check SPF record for the domain
function Get-SpfRecord {
    param ([string]$Domain)
    
    Write-Log "Checking SPF record for $Domain..."
    $txtRecords = Resolve-DnsName -Name $Domain -Type TXT
    $spfRecords = $txtRecords | Where-Object { $_.Strings -like "v=spf1*" }
    # ... log records ...
}

This code:

  • Uses native Windows tools (nslookup) for MX record verification
  • Identifies SPF records in DNS TXT entries
  • Logs the complete DNS configuration for reference

3. Comprehensive Logging

# Function to write to both console and log file (appends to existing file)
function Write-Log {
    param ([string]$Message)
    
    Write-Host $Message
    Add-Content -Path $logFile -Value $Message
}

The logging system:

  • Writes to both console and file for visibility and record-keeping
  • Uses a consistent log file for historical data
  • Timestamps all entries
  • Formats log entries for easy parsing by the dashboard generator

The Dashboard Generator Script

The second script transforms the raw log data into an informative, professional dashboard:

1. Log Parsing and Data Extraction

function Parse-LogFile {
    param ([string]$LogFilePath)
    
    # ... file reading logic ...
    
    # Split the log content into individual check sessions
    $sessions = $logContent -split "(?=======+\r?\nSMTP Server Check - Started at )"
    
    $sessionData = @()
    foreach ($session in $sessions) {
        # Extract timestamp, server, domain, MX records, SPF records, port checks
        # ... extraction logic ...
        
        $sessionData += $sessionInfo
    }
    
    # Sort by timestamp (newest first)
    $sessionData = $sessionData | Sort-Object -Property Timestamp -Descending
    
    return $sessionData
}

This function:

  • Parses the structured log file into discrete check sessions
  • Extracts all relevant data from each session
  • Organizes data chronologically for historical tracking

2. HTML Dashboard

function Generate-Dashboard {
    param ([array]$SessionData)
    
    # Get the latest session for summary info
    $latestSession = $SessionData[0]
    
    # HTML generation with CSS styling and JavaScript
    $html = @"
<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Meta tags, title, styles -->
    <style>
        /* Professional health-card styling */
        body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; ... }
        .summary-card { background-color: white; border-radius: 8px; ... }
        .status-indicator.status-success { background-color: #28a745; }
        .status-indicator.status-error { background-color: #dc3545; }
        <!-- More styling -->
    </style>
</head>
<body>
    <!-- Dashboard HTML structure -->
</body>
</html>
"@
    
    return $html
}

The dashboard features:

  • Current status summary at the top
  • Latest MX and SPF information prominently displayed
  • Color-coded health indicators (green/yellow/red)
  • Chronological history of checks
  • Version tracking for DNS changes
  • Responsive design that works on various devices

3. Persistent Change Tracking with JSON

One of the most important aspects of our monitoring system is tracking changes to critical DNS records over time. To accomplish this, we implemented a robust JSON-based tracking system:

# Path for the JSON files to store values and history
$lastValuesFile = "SMTPServerLastValues.json"
$historyFile = "SMTPServerChangeHistory.json"

# Function to normalize record strings to avoid false positives
function Normalize-RecordString {
    param ([array]$Records)
    return ($Records | ForEach-Object { $_.Trim() } | Where-Object { $_ }) -join "|"
}

# Get the latest session data
$latestSession = $SessionData[0]
$currentSpf = Normalize-RecordString -Records $latestSession.SpfRecords
$currentMx = Normalize-RecordString -Records $latestSession.MxRecords

# Load previous values
if (Test-Path $lastValuesFile) {
    $lastValues = Get-Content -Path $lastValuesFile -Raw | ConvertFrom-Json
}

# Check for SPF changes
if ($lastValues -and $currentSpf -ne $lastValues.SpfRecord) {
    $changes += @{
        Type = "SPF Record"
        Timestamp = $latestSession.Timestamp
        OldValue = $lastValues.SpfRecord
        NewValue = $currentSpf
    }
    # Update history file with new change
    # ...
}

# Save current values for next run
$currentValues = @{
    Timestamp = $latestSession.Timestamp.ToString()
    SpfRecord = $currentSpf
    MxRecords = $currentMx
    # ...
}
$currentValues | ConvertTo-Json | Set-Content -Path $lastValuesFile

This implementation:

  • Stores the most recent values in SMTPServerLastValues.json
  • Maintains a complete history of changes in SMTPServerChangeHistory.json
  • Uses normalization to prevent false positives from formatting differences
  • Only registers genuine changes to record content
  • Persists change history between script runs and server restarts
  • Displays changes chronologically in the dashboard's version history section

By using JSON files for persistence rather than relying solely on in-memory comparison or log parsing, our solution provides accurate change tracking over extended periods, even if logs are rotated or cleared.

Key Technical Features

1. Robust Error Handling

The scripts include comprehensive error handling to ensure they continue working even when servers are down or unresponsive:

try {
    # Test operation
} catch {
    Write-Log "Error details: $($_.Exception.Message)"
} finally {
    # Clean up resources
}

2. Performance Optimization

We optimized performance by:

  • Setting appropriate timeouts (5 seconds by default)
  • Removing unnecessary checks (TLS verification, traceroute) that slowed execution
  • Using efficient data structures for log parsing

3. Scalability

The solution scales well for monitoring multiple servers:

  • The server and domain variables can be easily modified to check different endpoints
  • The check script can be extended to monitor additional ports or services
  • The dashboard handles multiple servers and check sessions cleanly

Script Usage : Results

The implemented solution provided several benefits:

  1. Early Problem Detection: Issues with SMTP server connectivity are identified immediately through visual indicators
  2. Simplified Troubleshooting: The dashboard makes it easy to determine if problems are related to DNS configuration, port connectivity, or server response
  3. Historical Analysis: Trends in server performance can be tracked over time
  4. Accurate DNS Change Monitoring: The JSON-based tracking system ensures that only genuine changes to MX and SPF records are captured, eliminating false positives
  5. Persistent Record Keeping: Change history is maintained even if logs are rotated or the server is restarted
  6. Low Resource Utilization: The entire solution runs with minimal system impact

Deployment Options

This solution can be deployed in several ways:

  1. Scheduled Tasks: Run the check script at regular intervals (e.g., every 15 minutes) with the dashboard generator running afterward
  2. IIS Hosting: Host the HTML dashboard on an internal web server for team access
  3. Integration: Extend the scripts to send alerts via email or messaging platforms when failures are detected

Closing Thoughts and Summary

With just two PowerShell scripts, you can created a professional SMTP server monitoring system that provides real-time health status, historical tracking, and accurate change detection. This lightweight solution offers many of the features of commercial monitoring tools without complex installation or licensing costs.

The scripts are easily customizable to fit specific organizational needs and can be extended to monitor additional services beyond SMTP. Whether you're managing a small business email server or enterprise mail infrastructure, this monitoring approach provides valuable insights with minimal overhead.

By focusing on the core requirements and leveraging PowerShell's capabilities, we've delivered a solution that improves email infrastructure reliability through proactive monitoring and clear visualization of system health. The JSON-based persistence layer ensures that your monitoring data remains accurate and consistent over time.

Scripts

The script is not available on this blog because it’s quite lengthy so if you would like it, please email me at scripts@a6n.co.uk

Previous Post Next Post

نموذج الاتصال