This is the base code:
foreach ($event in Get-WinEvent -FilterHashtable @{LogName='Security';ID=5152}) {
$xml = [xml]$event.toxml();
$xml.event.eventdata.data |
foreach { $hash = @{} } { $hash[$_.name] = $_.'#text' } { [pscustomobject]$hash } |
Where FilterOrigin -notmatch 'stealth|unknown|Query User Default'
}
the output is this:
I want to replace FilterOrigin with Firewall Display name, direction with either inbound or outbound and protocol with correct name from here.
I just need to know how to do one or two of them, then I can do the rest myself once I know the syntax/pattern.
starting with FilterOrigin, I tried this:
foreach ($event in Get-WinEvent -FilterHashtable @{LogName='Security';ID=5152}) {
$xml = [xml]$event.toxml();
$xml.event.eventdata.data |
foreach { $hash = @{} } { $hash[$_.name] = $_.'#text' } { [pscustomobject]$hash } |
Where FilterOrigin -notmatch 'stealth|unknown|Query User Default' | ForEach-Object {
if ($_.filterorigin -match ($pattern = '{.+?}'))
{
$_.filterorigin -replace $pattern, (Get-NetFirewallRule -Name $Matches[0]).DisplayName
}
}
}
But the output is only the Firewall displaynames
, so it does recognize the Firewall name (which is the ID you see in the FilterOrigin
) but doesn't replace it inside the object.
for Protocol, let's say I only want to replace TCP (6)
and UDP (17)
, how should I do that?
for Direction, %%14592
is for inbound and %%14593
is for outbound
UPDATE:
foreach ($event in Get-WinEvent -FilterHashtable @{LogName='Security';ID=5152}) {
$xml = [xml]$event.toxml();
$xml.event.eventdata.data |
foreach { $hash = @{} } { $hash[$_.name] = $_.'#text' } { [pscustomobject]$hash } |
Where FilterOrigin -notmatch 'Stealth|Unknown|Query User Default|WSH Default' | ForEach-Object {
$pattern = '\{.+?\}'
$_.FilterOrigin = $_.FilterOrigin -replace $pattern, (Get-NetFirewallRule -Name $Matches[0]).DisplayName
$protocolName = @{ 6 = 'TCP'; 17 = 'UDP' }[$_.Protocol]
$_.Protocol = if (-not $protocolName) { $_.Protocol } else { $protocolName }
# Conceptually clearer PowerShell (Core) 7+ alternative:
$_.Direction = $_.Direction -eq '%%14592' ? 'Outbound' : 'Inbound'
# $_.Direction = ('Outbound', 'Inbound')[$_.Direction -eq '%%14592']
$_
}
}
So with this script, there are few problems,
in the picture, only the direction is being applied correctly. the filter that blocked the connection shown in the script has a name but it's name not showing up.
With the exception of ++
and --
(and compound assignments such as +=
, ...) PowerShell's operator do not perform in-place updates - instead they return (output) a result.
The -replace
operator is no exception, so for in-place updating you must assign the result of the operation back to the input variable:
$_.FilterOrigin =
$_.FilterOrigin -replace $pattern, (Get-NetFirewallRule -Name $Matches[0]).DisplayName
for Protocol, let's say I only want to replace TCP (6) and UDP (17), how should I do that?
$protocolName = @{ 6 = 'TCP'; 17 = 'UDP' }[[int] $_.Protocol]
$_.Protocol = if (-not $protocolName) { $_.Protocol } else { $protocolName }
for Direction, %%14592 is for inbound and %%14593 is for outbound
# Conceptually clearer PowerShell (Core) 7+ alternative:
# $_.Direction = $_.Direction -eq '%%14592' ? 'Outbound' : 'Inbound'
$_.Direction = ('Outbound', 'Inbound')[$_.Direction -eq '%%14592']