您好,脚本专家!

您好,脚本专家!

欢迎来到本 TechNet 专栏,在这里,Microsoft 脚本专家将为您解答与系统管理脚本编写有关的各种常见问题。遇到了系统管理脚本编写方面的问题?请将电子邮件发送到 scripter@microsoft.com。我们不能保证回答收到的所有问题,但是我们将尽最大的努力。

同时,不要忘了查看您好,脚本专家!存档

今日问题:如何检索已添加到事件日志中的最新事件的相关信息?


如何检索已添加到事件日志中的最新事件的相关信息?

问:

您好,脚本专家!如何检索已添加到事件日志中的最新事件的相关信息?

-- HG

答:

您好,HG。您要知道,好像就是昨天有人问过我们如何能够找到事件日志中的最旧事件。我们仍然记得我们是如何解答的 - 哦,对了:的确是昨天,难道不是吗?那么,就不要再浪费任何时间来回忆过去的美好时光了。(尽管总的看来,昨天确实很美好。)

好了,让我们言归正传。正如我们昨天说过的,每次向事件日志中添加事件时,都会为其分配一个顺序记录号:如果事件日志中有 1000 条记录,那么写入该日志的下一个事件将被分配记录号 1001。这意味着记录号最大的事件也将成为写入事件日志中的最新事件。要检索已添加到事件日志中的最新事件的相关信息,我们必须要做的就是确定哪个事件拥有最大的记录号。

但是,还是正如我们昨天说过的(伙计,我们昨天下了大功夫,是吧?),您无法编写一个可自动调用并检索具有最大记录号的事件的 WQL 查询;而是需要我们在查询中指定这个记录号。这才是问题所在:那么,到底怎样才能知道给定事件日志中当前所使用的最大记录号呢?

我们说过这是个问题吗?那么,抱歉,实际上这根本不是什么问题。请您先看下面这个脚本,它用于检索有关添加到事件日志中的最新事件的日期时间信息,然后让我们来告诉您这个秘密:

strComputer = "."
Set objWMIService = GetObject("winmgmts:{(Security)}\\" & _
        strComputer & "\root\cimv2")

Set colLogFiles = objWMIService.ExecQuery _
    ("Select * from Win32_NTEventLogFile where LogFileName='System'")

For Each objLogFile in colLogFiles
    intTotal = objLogFile.NumberOfRecords
Next

Set colEvents = objWMIService.ExecQuery _
    ("Select * from Win32_NTLogEvent Where Logfile = 'System' " & _
        "AND RecordNumber = " & intTotal)

For Each objEvent in colEvents
    Wscript.Echo "Time Written: " & objEvent.TimeWritten
Next

这就是其中的原理。我们首先连接到本地计算机上的 WMI 服务。然后,使用下面这个查询返回有关 System 事件日志的信息:

Set colLogFiles = objWMIService.ExecQuery _
    ("Select * from Win32_NTEventLogFile where LogFileName='System'")

请注意,我们在此处使用的是 Win32_NTEventLogFile 类;那是因为我们想要了解事件日志本身的属性的相关信息,而不是任何个别事件的相关信息。特别是想要知道 NumberOfRecords 属性的值;正如您可能已经猜到的那样,它将告诉我们事件日志中的记录数。为了得到这个数据,我们使用以下代码块遍历事件日志集合(由于我们指定的是 System 事件日志,所以集合中只有一项),然后将 NumberOfRecords 的值存储在一个名为 intTotal 的变量中:

For Each objLogFile in colLogFiles
    intTotal = objLogFile.NumberOfRecords
Next

为什么这样做?好吧,假定 System 事件日志中有 1001 条记录。这意味着写入该日志的最后一个事件的记录号将会是 1001。这就是怎样才能知道给定事件日志中当前所使用的最大记录号的方法:写入的最后一个事件的记录号将与日志中的事件数目相同。

考虑一下这个数学关系,您就会明白其中的工作原理了。如果事件日志中有一个事件,那么该事件的记录号将为 1。假定我们添加了另外一个事件。好了,现在我们有了 2 个事件,并且第二个事件的记录号将为 2。因为 2 等于 2,所以此方法有效。

剩下的问题都相当简单;对于 System 事件日志中的最新事件,我们按照昨天所使用的方法,使用以下几行代码返回并回显 TimeWritten 属性的值:

Set colEvents = objWMIService.ExecQuery _
    ("Select * from Win32_NTLogEvent Where Logfile = 'System' " & _
        "AND RecordNumber = " & intTotal)

For Each objEvent in colEvents
    Wscript.Echo "Time Written: " & objEvent.TimeWritten
Next

其中的秘密在于 WQL 查询,我们使用变量 intTotal 来检索拥有最大记录号的记录:RecordNumber = " & intTotal。这就是想要返回写入 System 事件日志的最后一个事件的相关信息时所必须完成的全部工作。

现在,我们进行到哪了?哦,对了。好像又回到了 1907 年的夏天,我们刚刚收到一封电报,向我们询问如何检索事件日志中的最旧事件。嗯,我们停下来想了一会儿,然后我们...。


更多信息

欢迎访问您好,脚本专家!- 存档

返回页首返回页首