Powershell: разбить массив на пары и сбросить, если не чередуется

У меня есть скрипт Powershell, который использует Get-EventLog искать события 6005, 6006, а также 6008 на удаленных серверах; после небольшой манипуляции он возвращает результаты в массиве.

$eventData += Get-EventLog -computerName $server_name -LogName system `
-After $prevMonthBegin -Before $prevMonthEnd |      
  Where-Object `
  { $_.eventid -eq 6005 -OR $_.eventID -eq 6006 -OR $_.eventID -eq 6008 } | 
  Select timegenerated, eventid, message, index, recordid | sort-object timegenerated

Я перебираю результаты и назначаю down или же up к $eventData.message поле и сортировать его снова timegenerated Это возвращает массив как так (извинения за форматирование):

$eventData | Sort-Object timegenerated | format-table

TimeGenerated EventID Индекс сообщения
------------- ------- ------- ----- --------
03.08.2014 5:30:02 утра 6006 вниз 0
03.08.2014 5:30:47 6005 до 0
24.08.2014 5:31:00 утра 6005 до 0
31.08.2014 2:34:59 утра 6008 вниз 1
31.08.2014 5:30:04 утра 6006 вниз 0
31.08.2014 5:30:59 утра 6005 до 0
31.08.2014 5:36:26 утра 6005 до 0

Как я могу создать новый массив из этих результатов и организовать TimeGenerated на пары вверх / вниз? Я бы предпочел не обращать внимания на первое событие массива, если оноup (так что всегда есть down затем up в парах), но я могу обойти это. Более важно никогда не иметь два последовательных down или же up события, как в примере вывода выше.

Я думал о, возможно, перебирая события и переключая временную переменную между 1 а также 0 (или же up а также down) но это кажется неуклюжим, и я просто не могу заставить что-либо работать. Это не должно быть так сложно, но именно поэтому я и прошу помощи. Дайте мне знать, было бы полезно предоставить больше кода; есть довольно много этого, и я не хотел просто сбрасывать страницы этого.

Вот пример формата для массива, который я хотел бы иметь. Метод, который я использую, связывает эти события как 12121212, не смотря на то, какие это типы событий. Таким образом, в приведенном выше примере, последняя пара событий будет рассчитывать время простоя, когда оно не существует, потому что было два up (6005) события.

Downtime            Uptime              CrashEvent?
8/3/2014 5:30:02 AM  8/3/2014 5:30:47 AM 0
8/24/2014 5:31:00 AM 8/31/2014 2:34:59 AM 0
8/31/2014 2:34:59 AM 8/31/2014 5:30:04 AM 1
8/31/2014 5:30:59 AM 8/31/2014 5:36:26 AM 0

2 ответа

Решение

Вот ответ, как это сделать, чтобы пропустить повторяющиеся записи. Тем не менее, вы, вероятно, захотите настроить запрашиваемые вами события, в противном случае вы в конечном итоге столкнетесь с условиями понижения / повышения, возникающими одновременно.

$Events = Get-EventLog -LogName system  |      
Where-Object { $_.eventid -eq 6005 -OR $_.eventID -eq 6006 -OR $_.eventID -eq 6008 } |
Select timegenerated, eventid, message, index, recordid | sort-object timegenerated


[array]$FullObj = [pscustomobject] @{
        'Time' = ''
        'Status' = ''
        'Message' = ''
        }

Foreach ($Event in $Events)
{ 
    If ($Event.Message -eq 'The Event log service was started.' -and $fullobj.status[-1] -ne 'UP')
    {
        [array]$FullObj += [pscustomobject] @{
        'Time' = $Event.TimeGenerated
        'Status' = 'UP'
        'Message' = $Event.Message
        }
    }
    Elseif ($fullobj.status[-1] -eq 'UP' -and $fullobj.Message[-1] -notlike "The previous system shutdown*")
    {
        [array]$FullObj += [pscustomobject] @{
        'Time' = $Event.TimeGenerated
        'Status' = 'DOWN'
        'Message' = $Event.Message
        }
    }
}

$FullObj | select time,status

Хорошо, это должно выбрать последнее из любого события "Вниз" или "Вверх" перед следующим типом противоположного типа (последний "Вниз" перед "Вверх" и последний "Вверх" перед "Вниз"), который, я думаю, является тем, что вы хотели. В основном совпадают каждый раз, когда система выходит из строя, со временем, когда она возвращалась, используя последнее уведомление о времени безотказной работы / простоях, если их несколько. Я думаю, что все ваше "Отмена первого любого последовательного дублированного типа события" ошибочно, но это именно так.

Коллекция событий, продублированная из Noah Sparks, с аргументом Select немного урезана. Затем он переходит в Switch, создавая пользовательский объект всякий раз, когда происходит событие Downtime, а затем устанавливает время работы для каждого события uptime и выводит его всякий раз, когда происходит следующее событие простоя, и начинает заново.

$Events = Get-EventLog -LogName system  |      
    Where-Object { $_.eventid -eq 6005 -OR $_.eventID -eq 6006 -OR $_.eventID -eq 6008 } |
        Select timegenerated, eventid | sort-object timegenerated
$record=$null
$Output = Switch($Events){
    {$_.EventID -match "600(6|8)"}{if(![string]::IsNullOrEmpty($Record.up)){$record}
                                   $Record=[pscustomobject][ordered]@{
                                       'Down'=$_.timegenerated
                                       'Up'=$null
                                       'Expected'=If($_.EventID -eq 6006){$true}else{$false}
                                   }}
    {$_.EventID -eq "6005"}{$Record.Up = $_.TimeGenerated}
}
$Output += $record
$Output

Лично я бы пошел с первым временем безотказной работы даже после того, как произошел случай простоя, но это только я. Это займет другое кодирование. Во всяком случае, результаты этого выглядят так (используя мои собственные записи журнала событий):

Down                           Up                                Expected 
----                           --                                -------- 
11/20/2013 8:47:42 AM          11/20/2013 8:49:11 AM                 True 
11/20/2013 3:50:14 PM          12/13/2013 9:14:52 AM                 True 
12/13/2013 9:26:21 AM          12/13/2013 9:27:42 AM                False 
12/13/2013 3:40:07 PM          12/13/2013 3:41:31 PM                 True 
1/9/2014 1:13:31 PM            1/16/2014 12:38:08 PM                 True 
1/16/2014 12:39:21 PM          1/16/2014 12:48:44 PM                 True 

Если вы посмотрите на второй список, я знаю, что мой компьютер не был сбит с 11/20 до 12/13, но отбрасывает первый из последовательных дубликатов, как это происходит. Если бы мы этого не сделали, это показало бы, что система возвращается в исходное состояние через одну минуту после сбоя, что гораздо более вероятно для моего компьютера.

Другие вопросы по тегам