В предыдущей части мы рассмотрели возможности управления журналами событий средствами .NET Framework, а так же рассмотрели проблематику использования .NET (из моего предыдущего блога) - Странности Get-Eventlog и не совсем богатый функционал. В этом посте мы разберём данный вопрос, но с использованием WMI и все примеры будут выполняться системе под управлением Windows Vista.
В WMI за журнал событий отвечают следующие классы:
- Win32_NTEventlogFile
- Win32_NTLogEvent
Win32_NTLogEventComputer
Win32_NTLogEventLog
Win32_NTLogEventUser
WMI, как и .NET поддерживает удалённую работу с использованием ключа -ComputerName, поэтому на этом заострять внимание не будем. За публикацию списка журналов в системе отвечает класс Win32_NTEventlogFile:
[vPodans] gwmi Win32_NTEventlogFile
FileSize LogfileName Name NumberOfRecords
-------- ----------- ---- ---------------
8458240 Application C:\Windows\System32\Winevt... 16154
69632 DFS Replication C:\Windows\System32\Winevt... 6
69632 HardwareEvents C:\Windows\System32\Winevt... 0
69632 Internet Explorer C:\Windows\System32\Winevt... 0
69632 Key Management Service C:\Windows\System32\Winevt... 0
69632 ODiag C:\Windows\System32\Winevt... 267
1118208 OSession C:\Windows\System32\Winevt... 524
20975616 System C:\Windows\System32\Winevt... 42472
12652544 Windows PowerShell C:\Windows\System32\Winevt... 14208
[vPodans]
Стандартная процедура вывода списка журналов в системе. А теперь и сами эвенты:
[vPodans] gwmi win32_ntlogevent -filter "logfile='application'" | select -first 1
Category : 0
Category String :
Event Code :
Event Identifier :
Type Event :
Insertion Strings :
Log File :
Message : The User Profile Service has started successfully.
Record Number :
Source Name :
Time Generated :
Time Written :
Type : Information
User Name :
[vPodans]
как бы информации не сильно много. Давайте немного приведём вид в более оперативный:
[vPodans] gwmi win32_ntlogevent -filter "logfile='application'" | select recordnumber, timegenerated, sourcename, eventc
ode, message -first 1 | ft -a
recordnumber timegenerated sourcename eventcode message
------------ ------------- ---------- --------- -------
1 20070710111520.000000-000 Microsoft-Windows-User Profiles Service 1531 The User Profile Service ha...
[vPodans]
уже более читабельно, кроме вывода даты. Чтобы подвести вывод даты и времени в формат [datetime] нужно воспользоваться конвертером времени:
[System.Management.ManagementDateTimeconverter]::ToDateTime("20070710111520.000000-000")
Чтобы привести итоговый вывод времени в укороченный формат даты и времени к данному выражению достаточно применить метод ToString().
([System.Management.ManagementDateTimeconverter]::ToDateTime("20070710111520.000000-000")).ToString()
[vPodans] [System.Management.ManagementDateTimeconverter]::ToDateTime("20070710111520.000000-000")
otrdiena, 2007. gada 10. julija 14:15:20
[vPodans] ([System.Management.ManagementDateTimeconverter]::ToDateTime("20070710111520.000000-000")).ToString()
10.07.07. 14:15:20
[vPodans]
А теперь всё сделаем так (с использованием хэш-таблиц), чтобы это всё на лету преобразовывалось и мы получили сразу готовый и более опрятный вывод:
$a = gwmi win32_ntlogevent -filter "logfile='application'" | select -first 1
$a | Select recordnumber, @{n="timegenerated";
e={([System.Management.ManagementDateTimeconverter]::ToDateTime($_.timegenerated)).tostring()}},
sourcename, eventcode, message | ft -AutoSize
[vPodans] $a = gwmi win32_ntlogevent -filter "logfile='application'" | select -first 1
[vPodans] $a | Select recordnumber, @{n="timegenerated";
>> e={([System.Management.ManagementDateTimeconverter]::ToDateTime($_.timegenerated)).tostring()}},
>> sourcename, eventcode, message | ft -AutoSize
>>
recordnumber timegenerated sourcename eventcode message
------------ ------------- ---------- --------- -------
1 10.07.07. 14:15:20 Microsoft-Windows-User Profiles Service 1531 The User Profile Service has start...
[vPodans]
вот так при помощи костылей мы привели вывод в нечто более божеское. В остальном WMI не представляет ничего интересного, что могло бы представиться полезным (за исключением возможности бэкапа журналов, которую я разобрал в предыдущем посте). Разобрать работу Win32_NTLogEventUser и Win32_NTLogEventComputer в принципе можно уже и самостоятельно.
Исходя из вышеизложенного можно понять, что WMI вариант управления эвентлогом не самый удобный и практичный. Но позволяет извлекать события из журналов Windows Vista/Windows Server 2008 в читабельном виде. При этом можно изменять различные параметры журналов событий которые описаны здесь: http://msdn.microsoft.com/en-us/library/aa394225(VS.85).aspx
Изменения делаются по одной общей схеме:
$EventLog = gwmi Win32_NTEventlogFile -Filter "logfilename = '$logfilename'"
$EventLog.Property = "New Property Value"
$EventLog.Put()
И в качестве последнего штриха приведу замеры скорости работы с эвентлогом с использованием .NET и WMI:
[user name] (measure-command {gwmi win32_ntlogevent -filter "logfile='application' and eventcode=8194"}).totalseconds
13.0865344
[user name] (measure-command {(new-object diagnostics.eventlog("application")).Entries | ? {$_.EventID -eq 8194}}).totalseconds
20.7334336
[user name]
[vPodans] (measure-command {gwmi win32_ntlogevent -filter "logfile='application' and eventcode=8194"}).totalseconds
18,0120719
[vPodans] (measure-command {(new-object diagnostics.eventlog("application")).Entries | ? {$_.EventID -eq 8194}}).totalseconds
13,3134996
[vPodans]
Как видим, для Windows Server 2003 более предпочтительным по скорости является WMI (от которого там толку не сильно много), а в Windows Vista - наоборот, .NET работает шустрее. Но из-за проблем с отображением событий журнала Security его польза в Windows Vista весьма сомнительна.