Powershell:将阵列拆分成对并丢弃,如果不交替

问题描述:

我有一个Powershell脚本,它使用Get-EventLog在远程服务器上搜索事件600560066008;经过一些操作后,它将返回数组中的结果。Powershell:将阵列拆分成对并丢弃,如果不交替

$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 

我遍历的结果,并分配任一downup$eventData.message字段和由timegenerated再次对它进行排序这将返回像这样(道歉格式化)的数组:

$eventData | Sort-Object timegenerated | format-table 

TimeGenerated EventID消息索引
------------- ------- ------- ----- --------
8/3/2014 5:30:02 AM 6006 down 0
2014年8月3日上午五点30分47秒6005向上0
2014年8月24日上午05时31分00秒6005向上0
2014年8月31日上午02时34分59秒6008向下1
2014年8月31日上午05时30分04秒6006下跌0
2014年8月31日上午05时三十分59秒6005了0
2014年8月31日上午05时36分26秒6005了0

我怎样才能从这些结果创建一个新的数组,并安排TimeGenerated上/下对?如果它是up(所以总是有down,然后up成对),我宁愿忽视阵列的第一个事件,但我可以解决这个问题。如上面的示例输出一样,永远不会有两个连续的downup事件更为重要。

我想通过事件也许迭代和切换10(或updown)之间的临时变量,但似乎笨重,我什么都做不了的工作。这不应该这么难,但这就是我寻求帮助的原因。让我知道是否提供更多的代码是有用的;有一个相当多的,我不想只是转储它的网页。

这里是我想要的数组格式的一个例子。我正在使用的方法将这些事件配对为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 
+0

你可以发布一个你想要的结果的例子吗?给定发布的输入数据? – mjolinor 2014-09-29 20:33:43

+0

我刚刚编辑了我的问题以包含此内容。谢谢。 – kiwisan 2014-09-29 20:42:48

+0

你只是在寻找有多久了?就像在8/31/2014 05:30:04 AM时一样,在2014年8月31日05:30:59回来了?这应该是可行的。 – TheMadTechnician 2014-09-29 20:43:40

下面是如何做到这一点的答案,应该跳过重复的条目。但是,您可能需要调整正在查询的事件,否则最终会出现同时发生向下/向上的情况。

$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 
+0

这很可爱,但它确实不是他想要的。 – TheMadTechnician 2014-09-29 21:52:49

+0

这是根据他写的。他的例子没有任何意义,因为当前两列已经显示出来,然后是正常的时候,碰撞值应该是什么?它可以被重做,没有太多的麻烦,只是在每一行上显示/停留时间,而不是我想的。无论哪种方式,尽管他所查询的数据对于这个目的来说是毫无价值的,监控时间应该用一个应用程序来完成这个目的。nagios有一个小型的免费版本,可能还有其他一些。 – 2014-09-29 22:32:11

+0

我同意他的样本数据是垃圾,并且很难确定他究竟想要什么,但他想要的输出格式相当清晰,我认为即使它与他的样本数据不匹配。仅供参考,6005是Windows即将上市,6006是计划关机,6008是意外关机,所以6008是他的崩溃数据是有道理的。 – TheMadTechnician 2014-09-29 22:39:30

确定,这应该选择最后先下一相反类型的任何递减或递增事件(一个之前下一页尾,和一个向下前上涨了),我认为这是你想要的。基本上匹配每次系统停机时间和恢复时间,如果连续有多个,则使用最后的正常运行时间/停机时间通知。我认为你的整个'丢弃任何顺序重复事件类型的第一个'是错误的,但是这确实如此。

从Noah Sparks复制的事件集合与选择参数修剪了一下。然后进入Switch,每当发生Downtime事件时创建一个自定义对象,然后设置每个正常运行时间的正常运行时间,并在下一次停机事件发生时重新输出。

$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,但丢弃它是如何碰到的第一个顺序重复。如果我们没有这样做,它会显示系统在下降一分钟后恢复,这对我的电脑来说更有可能。