Pulling EventLogs using powershell from a certain time period - powershell

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

Related

powershell get-eventlog add if more than 5 times

I am using:
"%windir%\system32\WindowsPowerShell\v1.0\powershell.exe" $log=Get-EventLog -LogName Security -InstanceID 4625 -After (Get-Date).AddDays(-60); if (($log)) {Write-Output $log[0].Message} ELSE {Write-Output 'WARNING-NoEventFound'}
This works perfect for me. I want to expand if possible and say write the output if the event happened more than 5 times. Similar to:
Count(*) > 5 that I would use in SQL.
I'd like to mention an alternative to Get-EventLog: Get-WinEvent
It usually has a lot better performance, both locally and over the network, it can do server side filtering with -FilterHashTable before sending the results. This can come in handy since Active Directory logs can be quite large sometimes.
Since you're only interested in if it's >5 results or not, we can also speed it up by breaking early when we have found 6 results, using -MaxEvents, and then just check whether we found 6 events or not.
$maxEvents = 6
$filterHashtable = #{
LogName = 'Security'
Id = 4625
StartTime = (Get-Date).AddDays(-60)
}
$log = Get-WinEvent -FilterHashtable $filterHashtable -MaxEvents $maxEvents
if ($log.Count -ge $maxEvents) {
#your code here
For readability I prefer to have the hashtable in a variable, but it can also be written inline like this, with ; as separator for the key value pairs:
Get-WinEvent -FilterHashtable #{ LogName = 'Security'; Id = ... }

Why do I get different results with Get-WinEvent versus Get-EventLog?

I'm trying to use Get-WinEvent to retrieve events from the eventlog for specific provider names that my company uses to write to the eventlog. I'm finding that I'm getting differing results depending on whether I use Get-WinEvent versus Get-EventLog, and I'm not sure why.
Using this test code (both provider names are proprietary names for different applications my company has):
$pName1 = "MagicFS6"
$pName2 = "MT_WPLAppServer"
$provider = $pName2
$fhash = #{
logname = 'application';
providername = $provider;
StartTime = '8/1/2017 12:00:00 AM'
}
$fhashevent = $null
$fhashevent = Get-WinEvent -FilterHashtable $fhash
$count = $fhashevent.Count
Write-Host "$provider had $count events using Get-WinEvent"
$eventlog = Get-EventLog -LogName Application -Source $provider -After '8/1/2017 12:00:00 AM'
$count = $eventlog.Count
Write-Host "$provider had $count events using Get-EventLog"
Running with $pName1 (MagicFS6), both Get-WinEvent and Get-EventLog return the same number of events. This tells me that the code is equivalent.
However, running with $pName2 (MT_WPLAppServer), Get-WinEvent returns 0 events, and Get-EventLog correctly returns thousands of results.
MagicFS6 had 12662 events using Get-WinEvent
MagicFS6 had 12662 events using Get-EventLog
MT_WPLAppServer had 0 events using Get-WinEvent
MT_WPLAppServer had 11483 events using Get-EventLog
For my needs, I need to use Get-WinEvent, so I would love some ideas on why this is not returning reliable results.

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

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

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.