← All posts

Auditing Windows Firewall Logging: The Dropped-Packet Log Everyone Forgets

Windows Firewall can log every dropped and allowed connection, but the log is off by default and capped at 4 KB. Here is how to turn it on, size it right, and audit it.

Ask most Windows admins where their firewall logs are and you get a blank stare. That is not carelessness — it is the default. The Windows Defender Firewall ships with logging disabled on all three profiles, and even when you turn it on, the log file is capped at a laughable 4096 KB and does not record dropped packets or successful connections unless you explicitly ask. The result is a host-based firewall that is silently doing its job with no forensic trail. When an incident happens and you go looking for "what did this box try to talk to at 3 a.m.," there is nothing there.

What the firewall log actually contains

When enabled, the firewall writes a W3C-format text log — by default %systemroot%\system32\LogFiles\Firewall\pfirewall.log. Each line records the timestamp, action (ALLOW / DROP), protocol, source and destination IP and port, packet size, TCP flags, and the direction (SEND / RECEIVE). Two settings decide what shows up:

Both are off by default. A firewall that only enforces but never records is a firewall you cannot audit after the fact.

The 4 KB trap

Even admins who enable logging often leave the size at the 4096 KB default. On a busy server that fills in minutes, and the firewall silently rolls it into pfirewall.log.old and starts over — so by the time you investigate, the window you care about has already been overwritten. Microsoft’s own security baselines (and CIS Benchmark 9.x) call for at least 16384 KB per profile, and on high-traffic hosts you want considerably more or a forwarder shipping the lines to a SIEM before they roll.

Turning it on, per profile

The firewall has three profiles — Domain, Private, Public — and each is configured independently. A common mistake is enabling logging on Domain but leaving Public (the profile a laptop uses on hostile networks) dark. Configure all three:

netsh advfirewall set domainprofile logging filename %systemroot%\system32\LogFiles\Firewall\pfirewall.log
netsh advfirewall set domainprofile logging maxfilesize 16384
netsh advfirewall set domainprofile logging droppedconnections enable
netsh advfirewall set domainprofile logging allowedconnections enable

# repeat for privateprofile and publicprofile
netsh advfirewall set allprofiles logging droppedconnections enable

Or with PowerShell, which is cleaner for automation:

Set-NetFirewallProfile -Profile Domain,Private,Public `
  -LogFileName '%systemroot%\system32\LogFiles\Firewall\pfirewall.log' `
  -LogMaxSizeKilobytes 16384 `
  -LogBlocked True -LogAllowed True

In a domain, do this through Group Policy under Computer Configuration → Windows Settings → Security Settings → Windows Defender Firewall with Advanced Security → (per-profile) Logging so it survives reimaging and cannot be flipped off locally.

Auditing what you already have

To read the current state without changing anything, query each profile:

Get-NetFirewallProfile -Profile Domain,Private,Public |
  Select-Object Name, LogBlocked, LogAllowed, LogMaxSizeKilobytes, LogFileName

What good looks like: LogBlocked and LogAllowed both True on every profile, LogMaxSizeKilobytes at 16384 or higher, and a LogFileName the SYSTEM account can actually write to. A subtle failure mode: the log directory ACL gets broken and the firewall service can no longer write, so logging reports as enabled but the file never grows. Check the file’s last-write time, not just the setting.

A firewall setting that says "logging: on" while pfirewall.log has not been touched in three weeks is worse than one that says off — it lies to you during the exact investigation you enabled it for.

Where WinSentinel fits

WinSentinel’s network posture audit checks all three profiles for logging state, minimum log size, and dropped/allowed-connection coverage — and flags the case where logging is nominally enabled but the log file is stale or unwritable. It rolls the finding up next to the rest of your firewall rule audit so "the firewall is enforcing but blind" shows up as a concrete, fixable finding rather than an assumption you never questioned. It is free, runs locally, and needs no agent:

dotnet tool install --global WinSentinel.Cli
winsentinel --audit network

Turning on the firewall was step one, a decade ago. Turning on its memory is the step almost everyone skipped — and it costs four commands.