我有一个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消息索引
----------------------------
2014年8月3日上午5:30:02 6006下跌0
2014年8月3日上午5:30:47 6005上行0
2014年8月24日上午5:31:00 6005以上0
2014年8月31日上午6:34:59下跌1
2014年8月31日上午5:30:04 6006下跌0
2014年8月31日上午5:30:59 6005以上0
2014年8月31日上午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
好的,这应该选择任何Down或Up事件中的最后一个,然后选择下一个相反类型的事件(上一个Down在Up之前,上一个Up在Down之前),我认为这就是你想要的。基本上,系统每次停机时都会与恢复时相匹配,如果连续出现多个,则使用上次正常运行时间/停机时间通知。我认为你的整个"放弃任何连续重复事件类型中的第一个"是错误的,但这确实是错误的。
事件集合与Noah Sparks重复,Select参数被稍微删减了一点。然后,它进入交换机,每当出现停机事件时创建一个自定义对象,然后为每个正常运行时间事件设置正常运行时间,并在下一个停机事件发生时输出,然后重新开始。
$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,但丢弃了顺序重复的第一个,这就是它的表现。如果我们不这样做,它会显示系统在停机一分钟后重新启动,这对我的电脑来说更有可能。
以下是如何跳过重复条目的答案。但是,您可能需要调整正在查询的事件,否则会同时出现向下/向上的情况。
$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