如何将PowerShell命令中Filter Origin替换为Windows防火墙显示名称?
修复PowerShell防火墙日志ID替换脚本
需求说明
原命令用于筛选Windows安全日志中ID为5152的出站非ICMP拦截事件,输出结果里的Filter Origin字段显示的是防火墙规则的GUID,需要替换为对应的规则显示名称,同时保留原输出格式:
Get-WinEvent -FilterHashtable @{ LogName="Security"; Id=5152; } | ? { $_.Message -like "*Outbound*" -and -not($_.message -like "*ICMP*")} | select Message | ft -wrap
原脚本问题分析
原脚本无法正常运行的核心原因:
- 正则捕获的内容包含大括号
{},但Get-NetFirewallRule -Name需要的是纯GUID字符串(不带大括号) - 未处理正则捕获组的内容,导致查询防火墙规则时匹配失败
修复后的脚本
# 获取目标事件并处理每条消息 Get-WinEvent -FilterHashtable @{ LogName="Security"; Id=5152; } | Where-Object { $_.Message -match "Outbound" -and $_.Message -notmatch "ICMP" } | ForEach-Object { # 替换Filter Origin后的GUID为显示名称 $modifiedMessage = $_.Message -replace '(?<=Filter Origin:\s*)\{([0-9a-fA-F-]+)\}', { # 提取不带大括号的GUID,查询对应规则的显示名称 $rule = Get-NetFirewallRule -Name $matches[1] -ErrorAction SilentlyContinue # 找不到规则时保留原GUID,否则返回显示名称 if ($rule) { $rule.DisplayName } else { $matches[0] } } # 输出保留原对象结构,仅替换Message字段 [PSCustomObject]@{ Message = $modifiedMessage } } | Format-Table -Wrap
关键修复点
- 正则调整为
(?<=Filter Origin:\s*)\{([0-9a-fA-F-]+)\},用捕获组提取纯GUID字符串($matches[1]) - 添加
-ErrorAction SilentlyContinue处理找不到规则的情况,避免报错 - 用
ForEach-Object逐个处理事件对象,保留原输出的对象结构,确保Format-Table -Wrap能正常工作
参考文档翻译(PowerShell比较运算符:使用脚本块替换)
当使用
-replace运算符时,可以将替换值指定为脚本块。对于每个匹配项,PowerShell会执行该脚本块,并将脚本块的输出作为替换文本。
在脚本块内部,可以通过$matches自动变量访问匹配的结果:
$matches[0]表示整个匹配的字符串$matches[N]表示第N个捕获组匹配的字符串
脚本块替换支持PowerShell 5.1及以上版本。
内容的提问来源于stack exchange,提问作者user20682592
相关产品推荐
相关产品推荐

