В предыдущей части мы рассмотрели возможности управления журналами событий средствами .NET Framework, а так же рассмотрели проблематику использования .NET (из моего предыдущего блога) - Странности Get-Eventlog и не совсем богатый функционал. В этом посте мы разберём данный вопрос, но с использованием WMI и все примеры будут выполняться системе под управлением Windows Vista.
В WMI за журнал событий отвечают следующие классы:
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 весьма сомнительна.
Comments: