Get-WinEvent查找所有错误



运行Get-WinEvent时可以使用通配符:

Get-WinEvent -filterhashtable 
@{logname="*";providername="*cluster*";starttime="04.01.2022";endtime="05.31.2022";level=2} - 
ErrorAction SilentlyContinue

但是对于logname和providername只使用通配符(令人惊讶的是)不会返回任何记录:

Get-WinEvent -filterhashtable 
@{logname="*";providername="*";starttime="04.01.2022";endtime="05.31.2022";level=2} - 
ErrorAction SilentlyContinue

so:如何在给定的时间范围内搜索来自每个提供者的每个日志中的所有错误?

StartTimeEndTime应该是类型为DateTime,但您提供字符串可以也可以不可以转换为datetime对象。
参见Get-WinEvent参数-FilterHashtable

由于为参数LogNameProviderName提供单个通配符*显然不起作用,您可以首先以字符串数组的形式检索系统中存在的所有有效logname和提供者名称,并使用它们:

# get an array of all Log names
$logNames     = [string[]](Get-WinEvent -ListLog *).LogName
# below line is bound to give you exceptions, so use SilentlyContinue
$logProviders = [string[]](Get-WinEvent -ListProvider * -ErrorAction SilentlyContinue).Name
$startDate    = (Get-Date -Year 2022 -Month 4 -Day 1).Date  # set to midnight
$endDate      = $startDate.AddMonths(2).AddDays(-1)         # calculate 2 months duration    
$filter       = @{LogName=$logNames; ProviderName=$logProviders; StartTime=$startDate; EndTime=$endDate; Level=2}
Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue 

使用像"04.01.2022"这样的字符串作为开始和结束日期可能在您的系统中工作,但是如果您在世界的不同部分,因此使用不同的系统语言环境,这些字符串很可能无法转换为DateTime对象。因此,最好使用文档中所述的正确数据类型。


根据文档参数LogName:

" Get-WinEvent cmdlet查询的Windows API有256个限制。这使得一次过滤所有日志变得困难。您可以通过使用循环遍历每个log">

来解决这个问题。也许使用像

这样的循环更好。
# below line is bound to give you exceptions, so use SilentlyContinue
$logProviders = [string[]](Get-WinEvent -ListProvider * -ErrorAction SilentlyContinue).Name
$startDate    = (Get-Date -Year 2022 -Month 4 -Day 1).Date  # set to midnight
$endDate      = $startDate.AddMonths(2).AddDays(-1)         # calculate 2 months duration 
Get-WinEvent -ListLog * | ForEach-Object {
$filter = @{LogName=$_.LogName; ProviderName=$logProviders; StartTime=$startDate; EndTime=$endDate; Level=2}
Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue
}

如何使用foreach-object循环。所有的日志名应该涵盖所有的提供者。在powershell 7中,您可以执行foreach-object -parallel,我花了不到2秒的时间。尝试枚举级别;我很惊讶它仍然需要强制转换为int。这可能是一个关于调用命令的问题。

$list = 1..10 | % tostring comp000
invoke-command $list {  # runs in parallel
get-winevent -listlog * -ea 0 | 
% { Get-WinEvent @{logname=$_.logname; 
starttime='4/1'; endtime='5/31'; 
level=[int][Diagnostics.Tracing.EventLevel]::Error} -ea 0 } 
}

最新更新