Share via

How to verify Remote Windows firewall (builtin Windows Defender Firewall with Advanced Security) status ?

EnterpriseArchitect 6,366 Reputation points
2026-04-01T12:30:42.3133333+00:00

What is the most reliable way to query the builtin Windows Defender Firewall with Advanced Security status on a Windows Server OS remotely?

 

New-CimSessionOption -Protocol Wsman combined with Get-NetFirewallProfile -CimSession $cimSession -ErrorAction Stop

 

The results are misleading because some servers appear enabled on all three profiles, but they are actually disabled.

Windows for business | Windows Server | User experience | PowerShell
0 comments No comments

Answer accepted by question author
  1. Tan Vu 1,940 Reputation points Independent Advisor
    2026-04-01T14:50:34.7966667+00:00

    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

    1 person found this answer helpful.
    0 comments No comments

1 additional answer

Sort by: Most helpful
  1. Q&A Assist
    2026-04-01T12:31:01.45+00:00
    AI generated content. This question contains an answer created with AI from Q&A Assist. Learn more

    Use the NetSecurity cmdlets that expose both per‑profile and global firewall state, and always query the active/enforced policy store.

    1. Query global firewall state (most important)

    Global firewall settings determine which profile is active and what is actually enforced, regardless of what individual profiles show. Use:

    # Remote global firewall settings
    $cim = New-CimSession -ComputerName <ServerName> -SessionOption (New-CimSessionOption -Protocol Wsman)
    Get-NetFirewallSetting -CimSession $cim
    

    The returned NetFirewallSetting object contains the global firewall configuration, including the active profile and enforced settings. This is the authoritative source for whether the firewall is effectively on or off, independent of what Get-NetFirewallProfile shows for each profile.

    1. Query per‑profile configuration from the enforced store

    Get-NetFirewallProfile shows the configuration for Domain, Private, and Public profiles, similar to the WFAS properties dialog. To ensure the values reflect enforced policy, query the active policy store (for example, ActiveStore when applicable):

    Get-NetFirewallProfile -CimSession $cim -All
    # or for specific profiles
    Get-NetFirewallProfile -CimSession $cim -Name Domain,Private,Public
    

    Use this output together with the global settings from Get-NetFirewallSetting to interpret whether a profile’s apparent state is actually in effect.

    1. Why Get-NetFirewallProfile alone can look misleading

    Get-NetFirewallProfile returns the configured options for each profile, but:

    • It reflects the profile configuration, not necessarily the currently active profile.
    • It does not by itself indicate which profile is active or whether global settings or higher‑priority policy sources are overriding the local configuration.

    Therefore, some servers can show all three profiles as “enabled” in Get-NetFirewallProfile, while global settings or the active profile mean the firewall is effectively disabled for the current network context.

    1. Recommended pattern for remote checks

    For a reliable remote check of firewall status on Windows Server:

    $cim = New-CimSession -ComputerName <ServerName> -SessionOption (New-CimSessionOption -Protocol Wsman)
    
    # 1. Global/enforced state
    $global = Get-NetFirewallSetting -CimSession $cim
    
    # 2. Per-profile configuration
    $profiles = Get-NetFirewallProfile -CimSession $cim -All
    
    $global
    $profiles
    

    Interpret the firewall status primarily from $global (active profile and global enforcement), and use $profiles to understand how each profile is configured.


    References:

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.