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.ps1PowerShell
# 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 $credentialUpdate 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
Press Windows key → type Task Scheduler → open it
Click "Create Basic Task" → name it
Firewall AuditTrigger: Weekly → Monday → 6:00am
Action: Start a program
Program:
powershell.exeArguments:
-ExecutionPolicy Bypass -File "C:\Scripts\FirewallAudit.ps1"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.


