How to replace Filter Origin in this PowerShell command with Windows Firewall's display name?

188 views Asked by At
Get-WinEvent -FilterHashtable @{ LogName="Security"; Id=5152; } | ? { $_.Message -like "*Outbound*" -and -not($_.message -like "*ICMP*")} | select Message | ft -wrap

Found that in here, after running it, the results look like this:

enter image description here

filter origin has this ID which is Firewall's unique name but I want to see a more user friendly name so I can understand immediately which Firewall rule, based on its display name that I set, blocked this connection.

Update: I want to do something like this. but it doesn't work like this and I need help fixing it. basically, I want to keep the same output format that the original script shows and only replace things like this {a42a62ec-83d9-4ab5-9d54-4dbd20cfab17} with their display name.

$data = (Get-WinEvent -FilterHashtable @{ LogName="Security"; Id=5152; } |
 ? { $_.Message -like "*Outbound*" -and -not($_.message -like "*ICMP*")}).message


 $data -replace "(?<=Filter Origin:[^{]+){.+?}",{(Get-NetFirewallRule -Name $Matches[0]).DisplayName}

https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_comparison_operators?view=powershell-7.2#replacement-with-a-script-block

2

There are 2 answers

9
Abraham Zinala On BEST ANSWER

Did a quick google search and saw this documentation on troubleshooting firewalls, and it points to Get-NetFireWallRule being able to get the display name from the ID. That said, you can use some handy RegEx of (?<=Filter Origin:[^{]+){.+?} to get the unique ID and query its friendly name:

Get-WinEvent -FilterHashtable @{ LogName="Security"; Id=5152; } |
    ? { $_.Message -like "*Outbound*" -and $_.Message -notlike "*ICMP*" } | 
    Select TimeCreated, @{
        Name = 'Msg'
        Expression = {
            if ($_.Message -match ($pattern = '(?<=Filter Origin:[^{]+){.+?}'))
            {
                $_.Message -replace $pattern, (Get-NetFirewallRule -Name $Matches[0]).DisplayName
            }
            else
            {
                $_.Message
            }
        }
    } | Ft -Wrap

Placing it inside an if statement allows it to leave the message alone if no match was found for patterns that may be the unique ID. See RegEx101 for more info on the pattern itself.

5
js2010 On

You can turn events into xml and access each field seperately. I don't have your exact event type.

$a = Get-WinEvent @{ LogName='Security' } -maxevents 1
$xml = [xml]$a.toxml()


$xml.event.eventdata.data

Name              #text
----              -----
SubjectUserSid    S-1-5-19
SubjectUserName   LOCAL SERVICE
SubjectDomainName NT AUTHORITY
SubjectLogonId    0x3e5
PreviousTime      2023-01-03T14:40:58.3894712Z
NewTime           2023-01-03T14:40:58.3975397Z
ProcessId         0x59c
ProcessName       C:\Windows\System32\svchost.exe


$xml.event.eventdata.data | ? name -eq processname | % '#text'

C:\Windows\System32\svchost.exe
Get-WinEvent @{ LogName='Security' } | % { $xml = [xml]$_.toxml()
  $xml.event.eventdata.data | ? name -eq 'processname' | % '#text' }