如何将PowerShell Get-EventLog输出中的%%代码替换为对应文本?
解析Windows事件日志中的%%错误代码为可读文本
当然可以搞定这个问题!那些以%%开头的字符串其实是Windows事件日志的消息ID,对应的可读说明存在系统的消息资源文件里,咱们用PowerShell就能轻松把它们转换成易懂的文本。
方法1:改造你现有的Get-EventLog命令
如果你想继续用原来的Get-EventLog脚本,可以通过[ComponentModel.Win32Exception]类来解析这些ID。修改后的代码如下:
Get-EventLog -ComputerName $computer -InstanceId 4625 -LogName Security -After $date -ErrorAction Stop | Select-Object TimeWritten, @{ Name = 'Reason for Failure'; Expression = { # 匹配%%开头的数字ID if ($_.ReplacementStrings[8] -match '^%%(\d+)$') { # 把ID转换成对应的错误消息 [System.ComponentModel.Win32Exception][int]$matches[1] | Select-Object -ExpandProperty Message } else { # 如果不是%%格式,直接返回原内容 $_.ReplacementStrings[8] } } }
原理说明
这段代码先用正则表达式提取%%后面的数字,然后借助Win32Exception类将数字ID映射成系统中存储的可读错误消息。比如:
%%2313会转换成Unknown user name or bad password.%%2304会转换成An error occurred during logon.
方法2:推荐用更现代的Get-WinEvent命令
Get-EventLog其实已经被微软标记为过时的cmdlet,更推荐使用Get-WinEvent——它不仅性能更好,还会自动解析事件消息,不用手动处理ReplacementStrings的索引(索引位置可能因系统版本变化)。
下面是用Get-WinEvent实现的版本:
Get-WinEvent -ComputerName $computer -FilterHashtable @{ LogName = 'Security' ID = 4625 StartTime = $date } -ErrorAction Stop | Select-Object TimeCreated, @{ Name = 'Reason for Failure'; Expression = { # 从已解析的Message属性中提取失败原因 $failureLine = $_.Message -split "`n" | Where-Object { $_ -match 'Failure Reason:' } ($failureLine -split ': ')[1].Trim() } }
这个版本直接从事件的Message属性里提取已经解析好的失败原因,结果会更准确也更稳定。
注意事项
- 如果你查询的是远程计算机,需要确保当前账号有读取远程事件日志的权限;
- 消息文本的语言取决于目标系统的语言设置,如果远程系统是中文,返回的就是中文说明,英文系统则返回英文。
内容的提问来源于stack exchange,提问作者ryanmaddock
相关产品推荐
相关产品推荐

