# PCS Toolkit - Firewall Security Audit # Checks critical firewall settings and security rules $timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" $logFile = "$env:USERPROFILE\Desktop\FirewallAudit_$timestamp.txt" function Log($msg) { Write-Host $msg Add-Content $logFile $msg } function LogWarn($msg) { Write-Host $msg -ForegroundColor Yellow Add-Content $logFile "[!] $msg" } function LogOK($msg) { Write-Host $msg -ForegroundColor Green Add-Content $logFile "[OK] $msg" } function LogBad($msg) { Write-Host $msg -ForegroundColor Red Add-Content $logFile "[!!] $msg" } Log "========================================" Log " PCS Toolkit - Firewall Security Audit" Log "========================================" Log "Generated: $(Get-Date)" Log "Computer: $env:COMPUTERNAME" Log "" # Check domain membership $cs = Get-CimInstance Win32_ComputerSystem $isDomainJoined = $cs.PartOfDomain Log "Domain Joined: $isDomainJoined" if ($isDomainJoined) { Log "Domain: $($cs.Domain)" } Log "" # ============================================ Log "=== FIREWALL PROFILE STATUS ===" # ============================================ $profiles = Get-NetFirewallProfile foreach ($p in $profiles) { Log "" Log "--- $($p.Name) Profile ---" if ($p.Enabled) { LogOK "Firewall Enabled: Yes" } else { LogBad "Firewall Enabled: NO - SECURITY RISK!" } Log " Default Inbound: $($p.DefaultInboundAction)" Log " Default Outbound: $($p.DefaultOutboundAction)" if ($p.DefaultInboundAction -eq 'Allow') { LogWarn "Default inbound is ALLOW - consider changing to Block" } } # Check which profile is currently active Log "" Log "=== ACTIVE NETWORK CONNECTIONS ===" $networks = Get-NetConnectionProfile foreach ($net in $networks) { Log "Interface: $($net.InterfaceAlias)" Log " Network: $($net.Name)" Log " Category: $($net.NetworkCategory)" if ($isDomainJoined -and $net.NetworkCategory -ne 'DomainAuthenticated') { LogWarn "Domain-joined PC but network is '$($net.NetworkCategory)' - may need domain connectivity" } } # ============================================ Log "" Log "=== RDP (Remote Desktop) ===" # ============================================ $rdpRules = Get-NetFirewallRule -DisplayName "*Remote Desktop*" -EA SilentlyContinue | Where-Object { $_.Enabled -eq 'True' } if ($rdpRules) { LogWarn "RDP is ENABLED in firewall" foreach ($rule in $rdpRules) { $port = ($rule | Get-NetFirewallPortFilter).LocalPort $addr = ($rule | Get-NetFirewallAddressFilter).RemoteAddress Log " Rule: $($rule.DisplayName)" Log " Direction: $($rule.Direction), Action: $($rule.Action)" Log " Port: $port, Remote: $addr" Log " Profile: $($rule.Profile)" if ($addr -eq 'Any' -or $addr -contains 'Any') { LogBad "RDP open to ANY address - restrict to specific IPs!" } } } else { LogOK "No enabled RDP rules found (RDP not exposed)" } # Check if RDP service is actually enabled $rdpSvc = Get-Service -Name TermService -EA SilentlyContinue $rdpEnabled = (Get-ItemProperty 'HKLM:\System\CurrentControlSet\Control\Terminal Server' -EA SilentlyContinue).fDenyTSConnections -eq 0 if ($rdpEnabled) { Log " RDP Service: Enabled (service: $($rdpSvc.Status))" } else { Log " RDP Service: Disabled at system level" } # ============================================ Log "" Log "=== SMB/FILE SHARING ===" # ============================================ $smbRules = Get-NetFirewallRule -DisplayName "*File and Printer Sharing*" -EA SilentlyContinue | Where-Object { $_.Enabled -eq 'True' -and $_.Direction -eq 'Inbound' -and $_.Action -eq 'Allow' } if ($smbRules) { LogWarn "File Sharing is ENABLED" $smbRules | Group-Object Profile | ForEach-Object { Log " Profile: $($_.Name) - $($_.Count) rules" } # Check if SMB is open to public profile $publicSMB = $smbRules | Where-Object { $_.Profile -match 'Public' -or $_.Profile -eq 'Any' } if ($publicSMB) { LogBad "SMB/File Sharing enabled on PUBLIC profile - security risk!" } } else { LogOK "File Sharing not enabled in firewall" } # ============================================ Log "" Log "=== WINRM (Remote Management) ===" # ============================================ $winrmRules = Get-NetFirewallRule -DisplayName "*Windows Remote Management*" -EA SilentlyContinue | Where-Object { $_.Enabled -eq 'True' } if ($winrmRules) { LogWarn "WinRM is ENABLED" foreach ($rule in $winrmRules) { $port = ($rule | Get-NetFirewallPortFilter).LocalPort Log " $($rule.DisplayName) - Port $port, Profile: $($rule.Profile)" } } else { LogOK "WinRM not enabled in firewall" } # ============================================ Log "" Log "=== SSH ===" # ============================================ $sshRules = Get-NetFirewallRule -EA SilentlyContinue | Where-Object { $_.Enabled -eq 'True' -and $_.Direction -eq 'Inbound' -and $_.Action -eq 'Allow' } | Where-Object { ($_ | Get-NetFirewallPortFilter).LocalPort -eq '22' } if ($sshRules) { LogWarn "SSH (port 22) is ENABLED" foreach ($rule in $sshRules) { Log " Rule: $($rule.DisplayName)" } } else { LogOK "SSH (port 22) not enabled" } # ============================================ Log "" Log "=== COMMON RISKY PORTS (Inbound Allow) ===" # ============================================ $riskyPorts = @{ '21' = 'FTP' '23' = 'Telnet' '25' = 'SMTP' '110' = 'POP3' '135' = 'RPC' '137' = 'NetBIOS' '138' = 'NetBIOS' '139' = 'NetBIOS' '445' = 'SMB' '1433' = 'SQL Server' '1434' = 'SQL Browser' '3306' = 'MySQL' '5432' = 'PostgreSQL' '5900' = 'VNC' '5985' = 'WinRM HTTP' '5986' = 'WinRM HTTPS' } $inboundAllow = Get-NetFirewallRule -Direction Inbound -Action Allow -Enabled True -EA SilentlyContinue $foundRisky = $false foreach ($rule in $inboundAllow) { $ports = ($rule | Get-NetFirewallPortFilter -EA SilentlyContinue).LocalPort if ($ports) { foreach ($port in $ports) { if ($riskyPorts.ContainsKey($port)) { if (-not $foundRisky) { $foundRisky = $true } LogWarn "Port $port ($($riskyPorts[$port])) open: $($rule.DisplayName)" } } } } if (-not $foundRisky) { LogOK "No commonly risky ports exposed" } # ============================================ Log "" Log "=== CUSTOM/3RD PARTY RULES ===" # ============================================ $customRules = Get-NetFirewallRule -EA SilentlyContinue | Where-Object { $_.Enabled -eq 'True' -and $_.Direction -eq 'Inbound' -and $_.Action -eq 'Allow' -and $_.Group -notlike '*Microsoft*' -and $_.Group -notlike '*Windows*' -and $_.Group -notlike '@*' -and $_.DisplayName -notlike '*Core Networking*' } if ($customRules) { Log "Found $($customRules.Count) custom inbound allow rules:" foreach ($rule in $customRules | Select-Object -First 15) { $port = ($rule | Get-NetFirewallPortFilter -EA SilentlyContinue).LocalPort $portStr = if ($port -and $port -ne 'Any') { " (Port: $port)" } else { "" } Log " $($rule.DisplayName)$portStr" } if ($customRules.Count -gt 15) { Log " ... and $($customRules.Count - 15) more" } } else { Log "No custom inbound rules found" } # ============================================ Log "" Log "=== RECOMMENDATIONS ===" # ============================================ Log "" $hasIssues = $false # Summarize key findings if (($profiles | Where-Object { -not $_.Enabled }).Count -gt 0) { LogBad "CRITICAL: Enable Windows Firewall on all profiles" $hasIssues = $true } if ($rdpRules) { $openRDP = $rdpRules | Where-Object { ($_ | Get-NetFirewallAddressFilter).RemoteAddress -eq 'Any' -or ($_ | Get-NetFirewallAddressFilter).RemoteAddress -contains 'Any' } if ($openRDP) { LogWarn "Restrict RDP to specific IP addresses or use VPN" $hasIssues = $true } } if ($smbRules | Where-Object { $_.Profile -match 'Public' }) { LogWarn "Disable file sharing on Public network profile" $hasIssues = $true } if (-not $hasIssues) { LogOK "No critical firewall issues found" } Log "" Log "========================================" Log "AUDIT COMPLETE" Log "========================================" explorer.exe "/select,$logFile" Read-Host "Press Enter to exit"