Powershell: как извлечь время из поля сообщений в Eventlog?
Я пытаюсь получить неожиданное время выключения компьютеров Windows Sever 2008 через Get-EventLog
в Powershell. Я могу приблизиться, ища события с EventID
из 6008 и выбрав только message
, но мне нужно проанализировать поле, чтобы получить время, когда оно произошло (а не время, когда событие сработало).
Я пытался использовать replacementstrings[x]
но я не могу найти, как указать поле для использования (messages
) и не могу получить результат.
get-eventlog -LogName System -ComputerName svr-name | Where-Object {$_.EventID -eq 6008 -AND $_.timegenerated -gt (get-date).adddays(-30)}| select message
Производит это:
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.`
3 ответа
Извлечение всех событий с удаленного хоста и их фильтрация на локальном компьютере обычно не слишком эффективны, потому что таким образом вы передаете тонны несвязанных событий по сети, просто чтобы выбросить их. Get-EventLog
имеет параметры для фильтрации сообщений по идентификатору события или до / после заданной отметки времени в источнике, поэтому лучше использовать их для предварительного выбора сообщений, которые вам действительно интересны. Отметку времени сбоя можно извлечь из Message
поле с регулярным выражением и анализируется в DateTime
значение через 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)}}
Конвейер создает список объектов со свойствами MachineName
, TimeGenerated
а также Crashtime
(последний является расчетным свойством). Если вы собираете выходные данные конвейера в переменную (например, $evt
) вы можете получить доступ к Crashtime
свойство третьего объекта, как это:
$evt = .\script.ps1
$evt[2].Crashtime
Используя регулярные выражения, вы можете вытащить его как таковой.
$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])"
}
}
Возможно, есть лучший способ, но я не знаю, что:)
Пример вывода из моей системы
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