尝试使用Get-WinEvent创建一个简单的Windows Update错误查询(尽管我更喜欢查询WMI对象以与SCUP一起使用):
get-winevent -logname System| Where-Object {$_.ProviderName -eq "Microsoft-Windows-WindowsUpdateClient"}
这似乎在大多数情况下都有效。但是,它只返回信息性事件,而不返回错误。这些是否位于其他地方?如果是,我将如何查询它们?出于某种背景,在我的环境中,大约10%的Windows 10计算机上发生了特定的更新失败(缺少程序集文件),我想将其作为目标,以便部署解决方案。
使用Get-WinEvent的解决方案是可以的,不过如果可能的话,我更喜欢使用Get-WMIObject。
您可以像这样使用Win32_NTLogEvent:
Get-WmiObject Win32_NTLogEvent |?{($_.LogFile -eq 'System') -and ($_.SourceName -eq 'Microsoft-Windows-WindowsUpdateClient') }
注意:您可以使用Type进行进一步筛选,它会告诉您有关信息、错误或警告的信息。
希望能有所帮助。
我找不到任何实际说明这一点的内容,但看起来Get-WinEvent
默认情况下只返回信息消息。如果你想看到另一个,那么你需要告诉它归还这些。一种方法是使用-FilterHashtable
。
Get-WinEvent -FilterHashtable @{LogName='System';Level=1,2}
这将只返回警告和错误。
1-错误
2-警告
4-信息
您可以查看枚举[System.Diagnostics.EventLogEntryType]
来查看我从哪里获得的数字。
看看MS,你可以看到哈希表过滤器支持什么。。
LogName=<String[]>
ProviderName=<String[]>
Path=<String[]>
Keywords=<Long[]>
ID=<Int32[]>
Level=<Int32[]>
StartTime=<DateTime>
EndTime=<DataTime>
UserID=<SID>
Data=<String[]>
*=<String[]>
如果你的WMI查询有类似的问题,那么你可以做一些类似的
Get-WmiObject -class Win32_NTLogEvent -filter "(logfile='Application') AND (type='error')"
你可以在这里找到一些切向的例子
编写WMI查询(这会覆盖奇怪的事件类型过滤器):
Get-WmiObject -Query "Select * from Win32_NTLogEvent" |?{(($_.LogFile -eq 'System') -and ($_.Type -in ("Error", "Warning"))) -and ($_.SourceName -eq 'Microsoft-Windows-WindowsUpdateClient') }
好吧,所以在做了一些额外的研究之后,我偶然发现了这个网站,它为我遇到的问题提供了一些线索。从本质上讲,虽然大多数(如果不是所有的Windows事件)都记录在C:\Windows\System32\Winevt\logs文件夹中,但默认情况下,并非所有Windows事件都复制在WMI中。
在PowerShell中,Get-WinEvent在查询其事件数据时似乎使用上面的文件夹,而Get-EventLog使用Win32_WinNTLogEventWMI类。
在我最初的问题中,我提到我无法使用Get-WinEvent查询WindowsUpdate错误事件。这是因为我指向的是不包含信息的系统日志文件。Microsoft Windows UpdateClient/Operative日志文件(文本路径为C:\Windows\System32\Winevt\logs\Microsoft Windows UpdateClient%4Operational.evtx)确实包含此信息,因此我的查询可以简单地使用类似于以下内容的内容进行更改:
Get-WinEvent -logname "Microsoft-Windows-WindowsUpdateClient/Operational" | Where-Object {$_.LevelDisplayName -eq "Error"}
为了使用Win32_NTLogEventWMI类查询Get-WinEvent返回的相同数据,必须首先修改注册表。同样,我在这个答案中发布的链接更详细地描述了这个过程,但本质上我执行了以下注册表mod:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesEventLogMicrosoft-Windows-WindowsUpdateClient/Operational]
"File"="%SystemRoot%\System32\Winevt\Logs\Microsoft-Windows-WindowsUpdateClient%4Operational.evtx"
"Primary Module"="Microsoft-Windows-WindowsUpdateClient/Operational"
"Microsoft-Windows-WindowsUpdateClient/Operational"=hex(2):25,00,53,00,79,00,73,00,74,
00,65,00,6d,00,52,00,6f,00,6f,00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,
65,00,6d,00,33,00,32,00,5c,00,77,00,65,00,76,00,74,00,61,00,70,00,69,00,2e,
00,64,00,6c,00,6c,00,00,00
注意:末尾的"Microsoft Windows WindowsUpdateClient/Operative"扩展字符串(REG_EXPAND_SZ)指向%SystemRoot%\system32\wevtapi.dll
一旦注册表被修改,我就可以查询如下错误事件:
Get-WmiObject -query "SELECT * FROM Win32_NTLogEvent WHERE LogFile='Microsoft-Windows-WindowsUpdateClient/Operational' AND Type='Error'"
考虑到默认情况下Win32_NTLogEvent WMI类(啊,Microsoft)中可能存在Windows Update错误,这有点痛苦。不过,这基本上解决了我的问题。
还有一点要提。上面的网站表示,编辑注册表后,您可以立即查询新事件。我必须先重新启动我的机器。