Purclot
Purclot

Reputation: 559

Get-WinEvent search for all errors

running Get-WinEvent it's possible to use wildcards:

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

but using only wildcards for both logname and providername (surprisingly) doesn't return any records:

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

so: how to search for all errors in every log from every provider in a given timespan?

Upvotes: 3

Views: 880

Answers (2)

js2010
js2010

Reputation: 27428

How I would do it with a foreach-object loop. All lognames should cover all providers. In powershell 7, you can do foreach-object -parallel, and it took me under 2 seconds. Trying an enum for level; I'm surprised it still needs casting to int. This may really be a question about invoke-command.

$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 } 
}

Upvotes: 2

Theo
Theo

Reputation: 61028

StartTime and EndTime should be of type DateTime, but you supply strings that may or may not be convertable to datetime objects.
See Get-WinEvent parameter -FilterHashtable

Since providing a single wildcard * for parameters LogName and ProviderName apparently doesn't work, you can first retrieve all valid lognames and provider names present in the system as string arrays and use those:

# 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 

Using the start and end date as strings like "04.01.2022" MAY work in your system, but if you are in a different part of the world and therefore use a different system locale these strings could very well not be convertable to DateTime objects. Therefore it is always best to use the correct datatype as stated in the documentation.


As per the docs parameter LogName:

"The Get-WinEvent cmdlet queries the Windows API which has a limit of 256. This can make it difficult to filter through all of your logs at one time. You can work around this by using a loop to iterate through each log",

perhaps better use a loop like

# 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
}

Upvotes: 1

Related Questions