Get-WinEvent with match TimeCreated

3.2k Views Asked by At

I'm looking to idea how to check whole Windows log for event matched particular date ex: At the moment stopped on "System" log :(

Get-WinEvent System | where {$_.TimeCreated -eq "24.03.2021 20:50:37"}

but results show me nothing. I want to use script to search all events not only System. I need to correlate date with events. My script looks like this:

(Get-WinEvent –ListLog * -ErrorAction SilentlyContinue).LogName | ForEach-Object {Get-WinEvent | where $_.TimeCreated -eq "24.03.2021 20:50:37"}}

but got syntax error

2

There are 2 best solutions below

4
On BEST ANSWER

I think the problem lies in the measure of accuracy you are after. (a date complete with Hours, Minutes and Seconds, but without the Milliseconds)

When you create a comparison DateTime object with

$time = [datetime]'03/24/2021 20:50:37'

you will find its .MilliSecond property is set to 0.

As you are comparing this to the events TimeCreated property, chances are very slim that date actually has that exact time with a MiliSecond also valued 0..

This is why you need to strip off the milliseconds (and also the fractions of those milliseconds) from the TimeCreated property of the events in order to be able to compare with an exact date, but without milliseconds:

$time = [datetime]'03/24/2021 20:50:37'
(Get-WinEvent -LogName System) | 
    Where-Object { ($_.TimeCreated.AddTicks(-$_.TimeCreated.Ticks % [timespan]::TicksPerSecond)) -eq $time } 

You can of course put this in a loop to scan different log names if you want


As per your comment, The Get-WinEvent cmdlet returns objects with a lot of properties. The standard way of PowerShell is to output on screen a subset of these properties, in this case TimeCreated, Id, LevelDisplayName and Message.

If you also want the name of the event log in this output, add a Select-Object to the command like:

$time = [datetime]'04/19/2021 08:38:20' 
(Get-WinEvent –ListLog * -ErrorAction SilentlyContinue).LogName | ForEach-Object {
    Get-WinEvent -LogName $_ | 
        Where-Object { ($_.TimeCreated.AddTicks(-$_.TimeCreated.Ticks % [timespan]::TicksPerSecond)) -eq $time} |
        # output the properties you are interested in
        Select-Object LogName, TimeCreated, Id, LevelDisplayName, Message
}

To make it more flexible, capture the result in a variable so you can both display on screen, and also save the results to a Csv file for later inspection:

$time   = [datetime]'04/19/2021 08:38:20' 
$result = (Get-WinEvent –ListLog * -ErrorAction SilentlyContinue).LogName | ForEach-Object {
    Get-WinEvent -LogName $_ | 
        Where-Object { ($_.TimeCreated.AddTicks(-$_.TimeCreated.Ticks % [timespan]::TicksPerSecond)) -eq $time} |
        # output the properties you are interested in
        Select-Object LogName, TimeCreated, Id, LevelDisplayName, Message
}

# output on screen
$result

# save to Csv File
$result | Export-Csv -Path 'Path\To\The\Output.csv' -NoTypeInformation -UseCulture

To see what all the properties returned are named, you can do
Get-WinEvent -LogName System | Select-Object -First 1 | fl *

0
On

TimeCreated is a DateTime type property, so a compatible string works better. (Not the same thing as starttime for a filterhashtable?)

Get-WinEvent system | select timecreated | select -first 1 | % timecreated | 
  % gettype

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     DateTime                                 System.ValueType


[datetime]'03/24/2021 20:50:37'

Wednesday, March 24, 2021 8:50:37 PM

# timecreated must have 0 milliseconds
get-winevent system | where timecreated -eq '03/24/2021 20:50:37'

One idea for the millisecond problem:

get-winevent system | where { $_.timecreated.tostring() -eq '3/24/2021 8:50:37 PM' }

I'm surprised something like this doesn't work.

get-winevent system | where '3/24/2021 8:50:37 PM' -eq timecreated


'3/24/2021 8:50:37 PM' -eq [datetime]'3/24/2021 8:50:37 PM'

False

Ugh got it. Tostring() doesn't format time this way.

[string][datetime]'3/24/2021 8:50:37 PM'

03/24/2021 20:50:37


'03/24/2021 20:50:37' -eq [datetime]'3/24/2021 8:50:37 PM'

True

So the left arg to -eq determines a string comparison:

get-winevent system | where '03/24/2021 20:50:37' -eq timecreated