Forum Discussion

joshlowit1's avatar
joshlowit1
Icon for Neophyte rankNeophyte
6 years ago

Monitor Firewall State

I have a client that has several servers that are part of an application group. Windows firewall has to be turned off on all the machines. Is there a way to monitor Windows Firewall to alert if the firewall is on for Private or Public?

5 Replies

  • Hey @joshlowit1,

    This one is a little trickier than it appears at first glance - firewall profile status/ activity isn't available through WMI, which leaves us with the command line - and PowerShell - meaning we need to do some scripting. There are a couple of relevant commands that return some information from Windows:

    I whipped up a quick PowerShell-based batchscript DataSource you can start with - it uses Get-NetFirewallProfile to determine if the firewall profiles are enabled - but unfortunately not if they are "connected." This ought to cover your use case though - if you have the profiles disabled for Domain, Public, and Private, and one becomes enabled (regardless of connection status,) this module should alert. (See the bottom of the post for a graphic that helps explain this confusing terminology.)

    Windows_Firewall_ProfileStatus has locator code CP6KLA and should be available for import as soon as I run it past our monitoring team.

    Let me know if you have any thoughts - it's a good bet that someone out there can integrate the "connected" profile piece with the enabled ones - with a little more work on the scripting side... 

    Cheers,

    Kerry

    NB: Here's the "collection" half of the DataSource for those interested - because we can monitor Windows both through integrated (and not) authentication, you'll notice that we use one of two different PowerShell remoting methods based on the presence of manually-defined credential properties:

    #LogicMonitor PowerShell Script Template 5.0
    
    #If present, ingest hostname and credentials from LogicMonitor device properties.
    $hostname = '##SYSTEM.SYSNAME##';
    $wmi_user = '##WMI.USER##';
    $wmi_pass = '##WMI.PASS##';
    
    #Are WMI credentials set? (Are the device properties unused or empty?)
    if ( (($wmi_user -like '*WMI.USER*') -and ($wmi_pass -like '*WMI.PASS*')) -or (($wmi_user -eq '') -and ($wmi_pass -eq '')) )
    {
        $use_credentials = $FALSE;
        $method = "Invoke-Command";
    }   
    
    else
    {
        #Convert username + password into a credential object for non-integrated domain authentication
        $use_credentials = $TRUE;
        $method = "Import-PSSession";
    
        $remote_pass       = ConvertTo-SecureString -String $wmi_pass -AsPlainText -Force;
        $remote_credential = New-Object -typename System.Management.Automation.PSCredential -argumentlist $wmi_user, $remote_pass;
    }
    
    #If we found credentials above, we will use them.
    if ( $use_credentials ) {
        #Establish a persistent remote PowerShell session from the collector to the device
        $session = New-PSSession -ComputerName $hostname -Authentication kerberos -Credential $remote_credential;
        
        #Import the remote PowerShell session and limit the amount of commands to import for efficiency
        Import-PSSession $session -CommandName Get-ADDomainController -AllowClobber | Out-Null;
    
        #Execute proxied remote commands on the local collector
        $profiles = Get-NetFirewallProfile -PolicyStore ActiveStore
        forEach($profile in $profiles) {
            $name = $profile.Name
            $enabled = $profile.Enabled
            switch($enabled)
            {
            "True" {$enabled = "1"}
            "False" {$enabled = "0"}
            }
            Write-Host $name".Enabled="$enabled
            }
        
        Remove-PSSession $session
        
        Exit
    }
    
    #If we did NOT find credentials above
    else {
        #Attempt integrated authentication using collector service account in the absence of credentials.
        Invoke-Command -ComputerName $hostname -ScriptBlock {
            #Execute remote commands remotely and capture the output
            $profiles = Get-NetFirewallProfile -PolicyStore ActiveStore
            forEach($profile in $profiles) {
            $name = $profile.Name
            $enabled = $profile.Enabled
            switch($enabled)
            {
            "True" {$enabled = "1"}
            "False" {$enabled = "0"}
            }
            Write-Host $name".Enabled="$enabled
            }
        } 
        
        Exit
    }
    
    Exit

    Windows Firewall example: (Domain Profile = Disabled, Connected. Private = Enabled, Not Connected. Public = Enabled, Not Connected. 

    The above datasource will alert on the instances for the Private and Public firewall profiles, as they are both enabled, regardless of connection status.

     

  • Hi Kerry,

    This worked great! I have tested it and it works like a charm. I really appreciate this!

    The only warning I have for anyone is that once you import it then it will apply to all Windows servers and since this monitors if the firewall is off and alerts if the firewall is on then be prepared to change isWindows() to False() really quick, otherwise it blows up your alert list. 

  • The issue I am having now is that after I run active discovery this Datasource is not applied to all of the Servers. There will be 1 server out of a group of five that is will not apply too. Any idea how I should go about troubleshooting that? 

  • Hey @Kerry DeVilbiss

    I went through and added the username and pass to the wmi.user and wmi.pass and this fixed a lot of them. I still have about 16 servers out of 112 that the script is applied to that are not working. I am getting 3 different errors when I test the script on the servers they need to be applied too. On 6 of them I get the message that No instances would be discovered. On 4 of them I get an error that it Failed to execute because there are no logon servers, all servers are in a workgroup none of the servers are domain joined. 6 of them get an error saying Failed to execute Kerberos cannot be used if not joined to a domain, as I stated above all 112 servers are not joined to a domain, so I do not know why I get this error with some but not others. 

  • Hi @Kerry DeVilbiss,

    The locator code in the current exchange is not working.

    I also tried to make my own DataSource following your example but it is now workin and I get a "There would be no instances discovered for the selected device." message when I try your example

    Can you check if the current version of LM needs another "Write-Host $name".Enabled="$enabled" syntax since I see different examples in the documentation when I look at
    https://www.logicmonitor.com/support/logicmodules/datasources/active-discovery/script-active-discovery/

    Regards,
    Jeroen