事件日志是操作系统用来保存本身及其他程序信息的工具,本文将会介绍如何通过PowerShell脚本阅读事件日志并创建新的日志条目。Windows系统中包含多种事件日志,在Windows XP系统中包括4种主要的事件日志。即应用程序、系统、安全性及Internet Explorer日志,如图1所示。这样用户可以方便地从系统中提取和查看日志,从而了解系统的当前运行情况。本文将会介绍如何通过PowerShell管理和创建Windows事件日志的方法。
1 管理事件日志
在使用事件日志时需要管理多个组件,其中最重要的是事件日志文件的大小。为了能够包括所需时间内的所有特定系统事件,通常情况下日志文件需要足够大,但是读取过大的文件将会耗费大量的时间。
(1)选择来源
使用事件日志时必须能够知道作为记录使用的日志,为此需要查看事件日志的源是否已经注册,实现这个目的的简单方法是使用WMI类Win32_NtEventLogFile。创建名为“GetLogSources.ps1”的脚本,其代码如下:
$strLog = "Application"
Write-Host "The following sources are registered for the $strLog log: `n"
Get-WmiObject Win32_nteventlogfile -Filter "logfilename like ‘%$strLog%’" |
foreach { $_.sources }
上述代码针对应用程序日志,也可以用于其他日志。首先使用Write-Host cmdlet输出将要搜索的标题字符串,通过Get-WmiObject cmdlet查询Win32_nteventlogfile WMI类并筛选来源信息中包括事件日志名称的事件。最后使用管道传递给ForEach-Object cmdlet以逐个输出来源名称,执行结果如图1所示。
图1 执行结果
(2)修改事件日志设置
存档策略对于系统日志很重要,不同策略决定留存的日志及其的时间。根据系统的特点,不同日志分类的存档策略决定系统的稳定和安全。通常情况下,事件日志的最大值(以KB为单位)、最短保留期(以天为单位),以及其他各种策略都有相应的留存策略。在Windows Vista和Windows 2008中主要有如下3个可以设置的存档策略。
Ø DoNotOverwrite:当事件日志达到限制的最大值时保存现有日志项,此后的系统日志将不会再被写入而丢失。
Ø OverwriteNeeded::当事件日志满后添加项会依次替换最早的项目。
Ø OverwriteOlder:当事件日志满后新的项目将会覆盖比MinimumRetentionDays属性值定义的时间更早的项。如果事件日志已满,而且没有其他项比该属性值定义的时间早,则丢弃新项。
创建用于查询系统日志存档策略的脚本文件GetEventLogRetentionPolicy.ps1,其代码如下:
$strLog = "Application"
$objLog = New-Object System.Diagnostics.Eventlog("$strLog")
Write-Host `
"
The current settings on the $($objlog.LogDisplayName) file are:
max kilobytes: $($objLog.maximumKiloBYtes)
min retention days: $($objLog.minimumRetentionDays)
overflow policy: $($objLog.overFlowAction)
"
其中使用New-Object cmdlet创建System.Diagnostics.Eventlog类的实例。在创建时需要传递指定参数用于确定需要处理的事件日志名,创建应用程序日志的对象后使用Write-Host cmdlet输出LogDisplayName、maximumKiloBYtes、minimumRetentionDays及overFlowAction属性。为了避免后3项只是简单地输出相关属性及其对象名称,为每个变量添加美元符(($)前缀并用括号分隔,如$($objLog.maximumKiloBYtes)。
该脚本的执行结果如图2所示。
图2执行结果
更改事件日志存档策略时也需要使用System.Diagnostics.Eventlog类来实现,还需要指定将要配置的是存档策略。ModifyOverFlowPolicy方法需要两个参数,即策略名和要使用的日期天数。在设置DoNotOverwrite或OverwriteAsNeeded时,忽略该方法调用的第2个参数。
创建脚本SetEventLogRetentionPolicy.ps1修改日志的存档策略,其代码如下:
function DisplayLogSettings()
{
Write-Host `
"
The current settings on the $($objlog.LogDisplayName) file are:
max kilobytes: $($objLog.maximumKiloBYtes)
min retention days: $($objLog.minimumRetentionDays)
overflow policy: $($objLog.overFlowAction)
"
if (!$args) { ChangeLogSettings("help") }
}
function ChangeLogSettings($policy)
{ if($policy -ne "help")
{
Write-Host -ForegroundColor green "changing log policy …"
}
switch($policy)
{
"doNotOW" { $objlog.modifyoverflowpolicy("DoNotOverwrite",-1) }
"owAsNeeded" { $objlog.modifyoverflowpolicy("OverwriteAsNeeded",-1) }
"owOlder" { $objlog.modifyoverflowpolicy("Overwriteolder",$intRetention) }
DEFAULT {
Write-Host -ForegroundColor red `
"
You need to specify either of the following: `n
doNotOW – do not overwrite logs
owAsNeeded – overwrite as needed
owOlder – overwrite events older than $intRetention days `n
Example: > SetEventLogRetentionPolicy.ps1 doNotOW
Sets retention policy to Do not Overwrite
Example: > SetEventLogRetentionPolicy.ps1 owAsNeeded
Sets retention policy to Overwrite as needed
Example: > SetEventLogRetentionPolicy.ps1 owOlder
Sets retention policy to Overwrite older than 30 days
Example: > SetEventLogRetentionPolicy.ps1 help
Displays this help message
"
exit }
}
}
$strLog = "application" #modify for different log
$intRetention = 30 #modify for different number of retention days
$objLog = New-Object system.diagnostics.eventlog("$strLog")
DisplayLogSettings($args)
ChangeLogSettings($args)
DisplayLogSettings($args)
注意在设置日志的存档策略时需要管理员权限;否则会出现错误,这是为了保护日志的有效性。如果低权限的非法用户试图恶意修改日志存档设置来逃避对操作的追查,则不可能。在脚本中初始化的变量$initRetention,默认值为30意味着事件日志存档策略会被设置为30天,当然只有在设置OverwriteOlder策略后才会生效。在脚本中使用$objLog变量保存System.Diagnostics.Eventlog类的实例,并定义要设置的事件日志名称。在创建并初始化这些对象后,需要调用DisplayLogSettings函数。该函数可以以KB为单位显示事件日志的大小上限,以天为单位显示最小留存时间及其超时后的操作。
在输出当前时间存档设置后退出函数,并继续处理脚本中剩余的代码。如果用户在运行脚本时未提供相关的参数,则使用help参数调用ChangeLogSetting函数,以输出详细的帮助信息并退出整个脚本的执行。
这个脚本的关键部分是ChangeLogSetting函数,它使用switch语句控制程序的逻辑。允许用户设置事件日志存档策略的参数,而不需要记忆复杂的System.Diagnostics.Eventlog类的语法。该switch语句的输入参数保存在配置文件$Profile中,用户在输入时分别匹配参数-donotw、-owasneeded及-owolder,分别对应于DoNotOverwrite、OverwriteNeeded和OverwriteOlder这3种存档策略。如果用户的输入未与其中的任何一个参数一致,则触发默认操作。这里的默认操作是用红色输出表现的帮助信息,这样可以帮助不熟悉此脚本的用户在执行出错后根据输出改进自己的输入。不带参数直接执行脚本的执行结果如图16所示,将存档策略由OverwriteOlder改变为DonotOverwrite后的执行结果如图3所示。
图3 不带参数执行脚本的结果
图17 将日志存档策略改为DonotOverwrite后执行结果
2 创建事件日志
用户可以通过创建事件日志来跟踪常见的操作以维护系统,为此使用System.Diagnostics.EventLog类的CreateEventSource方法,并提供事件日志的来源和名称。虽然一个事件日志可以保存多个来源的信息,但是一个事件来源只能关联一个事件日志。为了避免出错,需要使用SourceExist方法,并提供要查找的来源名称。如果来源不存在,则创建该来源和对应的事件日志;如果来源已经存在,则输出错误信息并退出脚本。CreateEventLog.ps1脚本创建事件日志,其代码如下:
$strProcess = get-WmiObject win32_process |
select-object name | out-string
$source = "ps_script"
$log = "PS_Script_Log"
if(![system.diagnostics.eventlog]::sourceExists($source,"."))
{
[system.diagnostics.eventlog]::CreateEventSource($source,$log)
}
ELSE
{
write-host "$source is already registered with another event Log"
EXIT
}
$strLog = new-object system.diagnostics.eventlog($log,".")
$strLog.source = $source
$strLog.writeEntry($strProcess)
如果事件来源已经注册给不同的事件日志并需要该来源使用自定义的事件日志,则必须首先删除该事件来源,为此可以使用system.diagnostics.eventlog类的DeleteEventSource方法。创建DelectEventSource.ps1脚本使用SourceExist方法判断事件来源是否已经被注册,如果已经注册,则使用LogNameFromSourceName方法输出该来源所指向的事件日志的名称。然后删除该事件来源,并传递已删除的消息;如果该事件来源尚未在系统注册,则会收到来源未注册的消息。该脚本的代码如下:
$source = "ps_script"
if([system.diagnostics.eventlog]::sourceExists($source,"."))
{
$log = [system.diagnostics.eventlog]::LogNameFromSourceName($source,".")
Write-Host "$source is currently registered with $log log."
Write-Host -ForegroundColor red "$source will be deleted"
[system.diagnostics.eventlog]::DeleteEventSource($source)
}
ELSE
{ Write-Host -ForegroundColor green "$source is not regisered" }
执行以上两个脚本后添加的事件日志可以通过系统的事件查看器(运行eventvwr.exe)看到。
3 总 结
本文介绍了通过PowerShell对Windows Vista和Windows Server 2008的事件日志进行管理的操作,包括使用Get-EventLog cmdlet生成可用的事件日志清单、创建自定义事件日志。
作者: 付海军
版权:本文版权归作者所有
转载:欢迎转载,为了保存作者的创作热情,请按要求【转载】,谢谢
要求:未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任
个人网站: http://txj.shell.tor.hu/