In Get-WinEvent, which kind of interval of EndTime? - powershell

I used Get-WinEvent in Powershell to get eventlog in a time interval. To avoid data loss or repeat, I need to know the interval type of StartTime and EndTime.
In the following example in MSDN:
PS C:\> # Use the Where-Object cmdlet
PS C:\>$yesterday = (Get-Date) - (New-TimeSpan -Day 1)
PS C:\>Get-WinEvent -LogName "Windows PowerShell" | Where-Object {$_.TimeCreated -ge $yesterday}
# Uses FilterHashTable
PS C:\>$yesterday = (Get-Date) - (New-TimeSpan -Day 1)
PS C:\>Get-WinEvent -FilterHashTable #{LogName='Windows PowerShell'; Level=3; StartTime=$yesterday}
It seems that StartTime means ">=".
But I did not find any info about EndTime. what's it represent? "<" or "<="?

EndTime means <=. Just ran a test on my PC. When I set EndTime=(get-date -Date "03.08.2015 14:07:27") I get events on that precise time. Also the timestamps in the event log don't contain milliseconds, therefore filtering is done by 1 second precision.

Related

Pulling EventLogs using powershell from a certain time period

I am trying to run a powershell script that will pull application event logs from between 2 certain times. I have the following code:
$Begin = Get-Date -Date '2/04/2022 14:36:00'
$End = Get-Date -Date '2/04/2022 14:40:00'
Get-EventLog –LogName Application -After $Begin -Before $End
I keep receiving the following error.
Get-Date : Cannot bind parameter because parameter 'Date' is specified more
than once. To provide multiple values to parameters that can accept multiple
values, use the array syntax. For example, "-parameter value1,value2,value3".
Does anyone know what I am doing wrong?
Get-Eventlog itself is depreciated.
You can use Get-Winevent like js2010 is suggesting.
-filterhashtable is (I believe) the only way to specify a time period.
$EventLogFilter = #{
Logname = 'System'
StartTime = [datetime]::Today.AddHours(-$Hours)
EndTime = [datetime]::Today
}
This would give you everything that happened in the last number of $hours you specify.
This is a list of key-value pairs.
An example with get-winevent's filterhashtable. Any string that can be converted to a datetime would work. Searching every log would require a foreach-object loop.
get-winevent -filterhashtable #{logname = 'application'; starttime = '12:45 pm';
endtime = '12:50 pm' }
ProviderName: gupdate
TimeCreated Id LevelDisplayName Message
----------- -- ---------------- -------
2/7/2022 12:45:19 PM 0

Comparing TICKS time in Powershell

I'm trying to compare two TICKS times, and i need the comparisons to be a little less precise and consider DateTime objects equal even if they were a few milliseconds apart (half minute tops) by removing any excess milliseconds and ticks from their DateTime objects (following jacubs guide).
problem is that my first ticks value ($date1) is generate from a performance counter, and i cannot convert him back to Date time again (Get-Date -Date ($date1)), getting the following error message:
Get-Date : Cannot bind parameter 'Date'. Cannot convert value
"636763462457113590" to type "System.DateTime". Error: "String was
not recognized as a valid dateTime"
This is my script:
$date1 = (Get-Counter -Counter '\TimeCheck\TIME').CounterSamples[0] | Select-Object -ExpandProperty RawValue
Get-Date $date1
Get-Date -Date ($date1) -Millisecond 0 | Select -ExpandProperty Ticks
$date2 = Get-Date
$date2.Ticks
Get-Date -Date ($date2) -Millisecond 0 | Select -ExpandProperty Ticks
$date1 -eq $date2
The only method this command works for me is if i wrote the TICKS time itself:
PS C:> Get-Date -Date 636763462457113590
Sunday, October 28, 2018 5:57:25 PM
What i'm doing wrong? even using out-string isn't working.
looks like $date1 in "Get-Date -Date ($date1)" is not numeric (based on error)
try Get-Date -Date ([int64]$date1) or [datetime][int64]$date1
this will convert from a tick count to a datetime object ...
$Ticks = 636763462457113590
$TimeFromTicks = [datetime]$Ticks
$TimeFromTicks
output = 2018 October 28, Sunday 5:57:25 PM

Get events from yesterday

I am trying to use PowerShell to get the results from the TaskScheduler events since yesterday. This is my code:
Get-WinEvent -LogName Microsoft-Windows-TaskScheduler/Operational -MaxEvents 5 |
Where-Object ($_.TimeCreated -gt [DateTime]::Today.AddDays(-1))
Format-List *
Notes:
The -MaxEvents 5 is to limit output while I am developing.
When I remove the Where-object the cmdlet returns a full list. This is expected since no filtering is applied. So the error must be in the way the filtering is being done.
You can use the FilterHashTable property of Get-WinEvent to filter, it will be faster than retrieving all the events and then filtering only those you want.
This retrieves all events in the last day from the System log as I don't have any logging for TaskScheduler.
$date = (Get-Date).AddDays(-1)
$events = Get-WinEvent -FilterHashTable #{ LogName = "System"; StartTime = $date;}
$events | Format-List
You can filter on pretty much any field in the event log - further info on this

converting datetime from wmiobject to datetime

Trying to get the difference in days between to dates: Today's date. and a date/time from a wmiobject (this was taken from a post from the PendingReboot script from Hey, Scripting! blog):
$Lastreboottime = Get-WmiObject win32_operatingsystem -ComputerName $Computer |
select csname, #{LABEL='LastBootUpTime';EXPRESSION=$_.ConverttoDateTime($_.lastbootuptime)}}
$Today = Get-Date -Format d
$DiffDays = $Today - $Lastreboottime
The result of $Today is
09/06/2016
and $Lastreboottime is
05/05/2016 11:13:21
So I want to get rid of the time but not sure how to do this.
Secondly, I get this error if I were to run the script, though I guess this may go away if I am able to extract the date only in $Lastreboot
Cannot convert the "#{csname=JDWTAWEB1; LastBootUpTime=05/05/2016 11:13:21}" value of type "Selected.System.Management.ManagementObject" to type "System.DateTime".
Any ideas?
Remove -Format d and compare the Date-properties of the DateTime-objects to get the days-diff only.
Your $Lastreboottime-variable references an object with both computername csname and the LastBootUpTime, so you need to access the LastBootUpTime
Try:
$Lastreboottime = Get-WmiObject win32_operatingsystem |
select csname, #{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
$Today = Get-Date
$DiffDays = $Today.Date - $Lastreboottime.LastBootUpTime.Date
$DiffDays.TotalDays
13
I think that the WMIObject conversion might need to get to a Datetime object by way of a properly formatted string. I did this (minus the -Computername $Computer part) and it seemed to work.
[string]$BootTimeString=(Get-WmiObject win32_operatingsystem -ComputerName $Computer).lastbootuptime -replace '\..*',''
$BootTimeDT=[datetime]::ParseExact($BootTimeString,'yyyyMMddHHmmss',$null)
$DiffDays = (NEW-TIMESPAN –Start $BootTimeDT –End (Get-Date)).Days
Remove -Format d from Get-Date. You need DateTime object, not a string.
$Lastreboottime is an object with 2 properties: csname and lastbootuptime. You have to use lastbootuptime property.
Example:
$Today = Get-Date
$DiffDays = $Today - $Lastreboottime.lastbootuptime

Powershell: How can I extract time from the message field of eventlog?

I'm trying to get unexpected shutdown times of Windows Sever 2008 machines via Get-EventLog in Powershell. I can get close by searching for events with an EventID of 6008 and selecting only message, but I need to parse within the field to grab the time it occurred (not the time the event fired).
I've tried to use replacementstrings[x] but I can't find how to specify the field to use (messages) and can't get a result.
get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30)}| select message
Produces this:
Message
-------
The previous system shutdown at 3:35:32 AM on ‎7/‎29/‎2014 was unexpected.
The previous system shutdown at 3:40:06 PM on ‎7/‎10/‎2014 was unexpected.`
Retrieving all events from a remote host and filtering them on the local machine ususally doesn't perform too well, because that way you transmit tons of unrelated events over the network, just to throw them away. Get-EventLog has options for filtering messages by Event ID or before/after a given timestamp on the source, so better use those for pre-selecting the messages you're actually interested in. The timestamp of the crash can be extracted from the Message field with a regular expression and parsed into a DateTime value via ParseExact():
$log = 'System'
$server = 'svr-name'
$id = [uint64]"0x80000000" + 6008
$date = (Get-Date).AddDays(-30)
$fmt = 'h:mm:ss tt on M\/d\/yyyy'
$culture = [Globalization.CultureInfo]::InvariantCulture
Get-EventLog -LogName $log -ComputerName $server -InstanceId $id -After $date | ? {
$_.Message -match 'at (\d+:\d+:\d+ [ap]m on \d+/\d+/\d+) was unexpected'
} | select MachineName, TimeGenerated,
#{n='Crashtime';e={[DateTime]::ParseExact($matches[1], $fmt, $culture)}}
The pipeline produces a list of objects with the properties MachineName, TimeGenerated and Crashtime (the last one being a calculated property). If you collect the output of the pipeline in a variable (e.g. $evt) you can access the Crashtime property of the third object like this:
$evt = .\script.ps1
$evt[2].Crashtime
Using regex, you can pull it out as such.
$Messages = (get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30) }| select message)
$Messages | ForEach-Object {
$Matched = $_.Message -match "([0-9]{1,2}:.*[0-9]{4})"
if ($Matched) {
Write-Output "System rebooted at $($Matches[1])"
}
}
There might be a better way, but I do not know what :)
Example Output from my System
System rebooted at 4:34:30 PM on ‎4/‎20/‎2014
System rebooted at 1:48:38 PM on ‎1/‎21/‎2014
System rebooted at 1:37:12 PM on ‎1/‎21/‎2014
System rebooted at 1:22:01 PM on ‎1/‎21/‎2014
System rebooted at 4:41:21 PM on ‎11/‎22/‎2013
More easy
get-eventlog system | where-object {$_.EventID -eq "6008"} | fl