简体   繁体   中英

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 (eg $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

更容易

get-eventlog system  | where-object {$_.EventID -eq  "6008"} | fl

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM