0

我有一个 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 消息索引
------------- ------- ------- ----- --------
8/3/2014 5 :30:02 AM 6006 向下 0
8/3/2014 5:30:47 AM 6005 向上 0 8/24/2014
5:31:00 AM 6005 向上 0
2014 年 8 月 31 日上午2:34:59 6008 下降 1 2014 年 8 月 31
日上午 5:30:04 6006 下降 0 2014 年 8
月 31 日上午 5:30:59 6005 上升 0 2014 年8 月 31
日 5:36 :26 AM 6005 向上 0

如何从这些结果中创建一个新数组并将它们排列成TimeGenerated上/下对?如果数组的第一个事件是一个,我宁愿忽略它up(所以总是成对出现),但我down可以up解决这个问题。更重要的是永远不要有两个连续的downup事件,如上面的示例输出所示。

我在考虑可能遍历事件并在1and 0(或upand 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
4

2 回答 2

3

好的,这应该在相反类型的下一个之前选择任何 Down 或 Up 事件中的最后一个(最后一个 Down 在 Up 之前,最后一个 Up 在 Down 之前),我认为这是你想要的。基本上每次系统关闭时匹配,与它恢复的时间相匹配,如果连续有多个,则使用最后的正常运行时间/停机时间通知。我认为您的整个“丢弃任何顺序重复事件类型中的第一个”是错误的,但这正是这样做的。

从 Noah Sparks 复制的事件集合,其中 Select 参数被修剪了一点。然后它进入 Switch,只要有 Downtime 事件就创建一个自定义对象,然后为每个 uptime 事件设置 uptime,并在下一个 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 停机,而是丢弃了第一个连续重复项,这就是它遇到的方式。如果我们不这样做,它会显示系统在停机一分钟后恢复,这对我的计算机来说更有可能。

于 2014-09-29T22:30:29.100 回答
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
于 2014-09-29T21:30:39.037 回答