In partnership with

THE PROBLEM

Firewall rules accumulate over years. A developer opens a port for testing and forgets to close it. A legacy application leaves rules nobody understands. A misconfigured rule exposes an internal service to the entire network. Most teams have no idea what rules are actually active across their servers — until an auditor or attacker finds out first. This week we build a script that audits every firewall rule across your environment and emails you a weekly report flagging anything suspicious.

THE SCRIPT

Save the script below to:

C:\Scripts\FirewallAudit.ps1

PowerShell

# Windows Firewall Rule Auditor
# Automate & Operate — automateandoperate.com

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

# Servers to audit
$servers = @(
    "localhost",
    "SERVER01",
    "SERVER02"
)

# Ports considered high risk — flag these in the report
$highRiskPorts = @(
    "21",    # FTP
    "23",    # Telnet
    "3389",  # RDP
    "445",   # SMB
    "135",   # RPC
    "5900",  # VNC
    "4444",  # Metasploit default
    "8080",  # Alt HTTP
    "1433",  # SQL Server
    "3306"   # MySQL
)

# 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 = @()
$flaggedRules = @()

foreach ($server in $servers) {
    try {
        $rules = Invoke-Command -ComputerName $server -ScriptBlock {
            Get-NetFirewallRule | Where-Object { $_.Enabled -eq "True" } | ForEach-Object {
                $rule = $_
                $portFilter = $rule | Get-NetFirewallPortFilter
                $addressFilter = $rule | Get-NetFirewallAddressFilter

                [PSCustomObject]@{
                    Name          = $rule.DisplayName
                    Direction     = $rule.Direction
                    Action        = $rule.Action
                    LocalPort     = $portFilter.LocalPort
                    RemoteAddress = $addressFilter.RemoteAddress
                    Profile       = $rule.Profile
                    Enabled       = $rule.Enabled
                }
            }
        } -ErrorAction Stop

        foreach ($rule in $rules) {
            $isHighRisk = $false
            foreach ($port in $highRiskPorts) {
                if ($rule.LocalPort -contains $port) {
                    $isHighRisk = $true
                    break
                }
            }

            $isOpenToAll = $rule.RemoteAddress -contains "Any" -and $rule.Action -eq "Allow"
            $riskLevel = if ($isHighRisk -and $isOpenToAll) {
                "HIGH"
            } elseif ($isHighRisk -or $isOpenToAll) {
                "MEDIUM"
            } else {
                "LOW"
            }

            $report += [PSCustomObject]@{
                Server        = $server
                RuleName      = $rule.Name
                Direction     = $rule.Direction
                Action        = $rule.Action
                LocalPort     = $rule.LocalPort -join ", "
                RemoteAddress = $rule.RemoteAddress -join ", "
                RiskLevel     = $riskLevel
            }

            if ($riskLevel -eq "HIGH") {
                $flaggedRules += [PSCustomObject]@{
                    Server   = $server
                    RuleName = $rule.Name
                    Port     = $rule.LocalPort -join ", "
                }
            }

            Add-Content -Path $logFile -Value "$timestamp$server$($rule.Name) — Port: $($rule.LocalPort) — Risk: $riskLevel"
        }

    } catch {
        Add-Content -Path $logFile -Value "$timestamp$server — ERROR: $_"
        $report += [PSCustomObject]@{
            Server        = $server
            RuleName      = "UNREACHABLE"
            Direction     = "N/A"
            Action        = "N/A"
            LocalPort     = "N/A"
            RemoteAddress = "N/A"
            RiskLevel     = "ERROR"
        }
    }
}

# Export CSV
$report | Export-Csv -Path $reportFile -NoTypeInformation

# Build email body
$emailBody = "Windows Firewall Audit Report — $timestamp`n"
$emailBody += "Servers audited: $($servers -join ', ')`n"
$emailBody += "Total rules reviewed: $($report.Count)`n"
$emailBody += "High risk rules found: $($flaggedRules.Count)`n`n"

if ($flaggedRules.Count -gt 0) {
    $emailBody += "HIGH RISK RULES — REVIEW IMMEDIATELY:`n"
    $emailBody += "=" * 60 + "`n"
    foreach ($flagged in $flaggedRules) {
        $emailBody += "Server:    $($flagged.Server)`n"
        $emailBody += "Rule:      $($flagged.RuleName)`n"
        $emailBody += "Port:      $($flagged.Port)`n"
        $emailBody += "-" * 40 + "`n"
    }
} else {
    $emailBody += "No high risk rules detected.`n"
}

$emailBody += "`nFull report saved to: $reportFile`n"
$emailBody += "`nAutomate & Operate — automateandoperate.com"

# Set subject based on findings
$subject = if ($flaggedRules.Count -gt 0) {
    "FIREWALL ALERT: $($flaggedRules.Count) high risk rule(s) found across $($servers.Count) server(s)"
} else {
    "Firewall Audit Complete — No high risk rules detected"
}

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

  • $servers — replace with your actual server names

  • $highRiskPorts — add or remove ports based on your environment

SETTING UP TASK SCHEDULER

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

  2. Click "Create Basic Task" → name it Firewall Audit

  3. Trigger: Weekly → Monday → 6:00am

  4. Action: Start a program

  5. Program: powershell.exe

  6. Arguments:

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

Every Monday morning you'll have a complete firewall audit report before the week starts.

TEST IT

Open PowerShell as administrator and run:

PowerShell

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

Check C:\Logs\FirewallAuditReport.csv — it will list every enabled firewall rule across all your servers with risk levels assigned. Check C:\Logs\FirewallAudit.log to confirm it ran correctly.

WHY THIS MATTERS

Firewall misconfiguration is one of the top causes of internal network breaches. A single "Allow Any" rule on RDP or SMB can expose your entire server to lateral movement once an attacker gets a foothold. This script gives you a weekly paper trail proving you actively monitor your firewall posture — invaluable for compliance audits and incident response.

THIS WEEK'S ACTION

Run this against localhost first. Review the CSV output and look for any Allow rules pointing to high risk ports. You might be surprised what you find on your own machine — let alone your servers.

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.

Learn how to code faster with AI in 5 mins a day

You're spending 40 hours a week writing code that AI could do in 10.

While you're grinding through pull requests, 200k+ engineers at OpenAI, Google & Meta are using AI to ship faster.

How?

The Code newsletter teaches them exactly which AI tools to use and how to use them.

Here's what you get:

  • AI coding techniques used by top engineers at top companies in just 5 mins a day

  • Tools and workflows that cut your coding time in half

  • Tech insights that keep you 6 months ahead

Sign up and get access to the Ultimate Claude code guide to ship 5X faster.

Keep Reading