Hi EnterpriseArchitect,
You're right to be suspicious of Get-NetFirewallProfile via CIM/WSMan - it reads from the policy layer, not the runtime enforcement state.
The cmdlet returns the configured profile settings, but does not reflect:
- Group Policy overrides (GPO can disable firewall silently)
- The actual runtime state as seen by the Service Control Manager
- Cases where the mpssvc service is stopped/disabled
The most common reason for your false positives is GPO disabling the firewall at the registry level while Get-NetFirewallProfile still reports the local configured state as "Enabled."
You can try some the following methods:
Method 1: Query the Firewall Service State Directly
$servers = @("Server01", "Server02", "Server03")
foreach ($server in $servers) {
$session = New-CimSession -ComputerName $server `
-SessionOption (New-CimSessionOption -Protocol Wsman)
# Check the actual Windows Firewall service (mpssvc)
$svc = Get-CimInstance -CimSession $session `
-ClassName Win32_Service `
-Filter "Name='mpssvc'"
[PSCustomObject]@{
Server = $server
ServiceState = $svc.State # Running / Stopped
StartMode = $svc.StartMode # Auto / Disabled / Manual
}
}
If mpssvc is Stopped or Disabled, the firewall is effectively off regardless of what Get-NetFirewallProfile reports.
Method 2: Read Runtime State via netsh Remotely (ground truth)
$servers = @("Server01", "Server02", "Server03")
foreach ($server in $servers) {
$result = Invoke-Command -ComputerName $server -ScriptBlock {
netsh advfirewall show allprofiles state
}
Write-Host "=== $server ===" -ForegroundColor Cyan
$result | Select-String "State"
}
netsh advfirewall reads the actual runtime enforcement state, not the policy layer. This is the most accurate single command you can run.
Method 3: Combined Check (Service + Profile + GPO) (most complete)
$servers = @("Server01", "Server02", "Server03")
$results = Invoke-Command -ComputerName $servers -ScriptBlock {
# 1. Service runtime state
$svc = Get-Service -Name mpssvc
# 2. Actual netsh runtime state
$netsh = netsh advfirewall show allprofiles state
# 3. GPO-applied state (if any)
$gpoFW = (Get-ItemProperty -Path `
"HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\DomainProfile" `
-Name "EnableFirewall" -ErrorAction SilentlyContinue).EnableFirewall
[PSCustomObject]@{
Server = $env:COMPUTERNAME
ServiceStatus = $svc.Status
StartType = $svc.StartType
NetshState = ($netsh | Select-String "State") -join " | "
GPO_Override = if ($null -eq $gpoFW) { "No GPO" }
elseif ($gpoFW -eq 1) { "GPO Enabled" }
else { "GPO DISABLED" }
}
}
$results | Format-Table -AutoSize
Always combine Method 1 + Method 2 at minimum. If GPO is in your environment, add the registry check from Method 3 to catch the silent GPO override scenario.
Note: "Server01", "Server02", "Server03" is example name, you must write your server.
If this helps resolve your issue, feel free to mark the answer so others can benefit as well.
TV