PowerShell技巧:提取Get-WinEvent的Message首行并统计安全日志
解决方法
刚接触PowerShell踩坑太正常了,我帮你写了个能直接满足需求的命令,顺便拆解下每个部分的逻辑,方便你理解:
Get-WinEvent -FilterHashtable @{logname="security"} | ForEach-Object { # 分割Message内容,提取第一行描述 $firstLine = $_.Message -split "`n|`r`n" | Select-Object -First 1 # 输出包含核心字段的自定义对象 [PSCustomObject]@{ ID = $_.Id Count = 1 Message = $firstLine.Trim() # 清理首尾多余空白 } } | Group-Object ID, Message -NoElement | Select-Object @{Name='Count'; Expression={$_.Count}}, @{Name='Name'; Expression={$_.Group[0].ID}}, @{Name='Message'; Expression={$_.Group[0].Message}} | Sort-Object Count -Descending
命令逻辑拆解:
- 第一步:
Get-WinEvent拉取安全日志的所有事件,这部分你原来的命令已经用对了; - 第二步:用
ForEach-Object逐个处理事件,通过-split "n|rn"把多行的Message按换行符分割,再用Select-Object -First 1取首行,最后包装成包含ID、临时Count(设为1)和提取的Message`的自定义对象; - 第三步:
Group-Object ID, Message按事件ID和对应的描述分组——同一个事件ID的首行描述肯定是一致的,这样分组后就能统计出每个ID的总出现次数; - 第四步:
Select-Object把分组结果整理成你要的三列格式,最后按Count降序排序,方便你一眼看到出现最多的事件;
小提示:
如果安全日志量很大,直接跑全量可能会卡,你可以先加-MaxEvents参数做测试,比如:
Get-WinEvent -FilterHashtable @{logname="security"} -MaxEvents 100 | # 后面的命令和上面一样
另外,如果遇到个别事件的Message为空的情况,可以加个判断避免空值:
$firstLine = if ($_.Message) { $_.Message -split "`n|`r`n" | Select-Object -First 1 } else { "无事件描述" }
内容的提问来源于stack exchange,提问作者The-Witcher
相关产品推荐
相关产品推荐

