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?
CodePudding user response:
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.
get-winevent -listlog * -ea 0 |
% -parallel { Get-WinEvent @{logname=$_.logname;
starttime='4/1'; endtime='5/31';
level=[int][Diagnostics.Tracing.EventLevel]::Error} -ea 0 }
CodePudding user response:
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
}