В продолжении темы работы с журналом собитый (EventLog) хочу немного рассказать об удалённой работе с EventLog и основными задачами управления. При этом хочу отметить, что у нас есть 2 различных механизма управления:
Но в зависимости от архитектуры ОС оба метода обладают различными характеристиками по времени работы, отображению событий и нагрузке системы. Забегая вперёд скажу, что использование чистого .NET в Windows Server 2003 занимает хоть и немного больше времени, но загрузка процессора ниже, чем у WMI. А вот в Windows Vista .NET работает быстрее по времени и с меньшей нагрузкой на процессор. Однако, учитывая нюансы, которые изложены здесь: Странности Get-Eventlog и тот факт, что командлет Get-Eventlog основан на .NET, то его применимость в условиях Windows Vista/2008 весьма сомнительна. Поэтому вариант с использованием .NET я буду писать применимо для Windows XP/2003.
Начнём с простого: управление журналом событий реализовано в классе System.Diagnostics.Eventlog. Для перечисления списка журналов можно воспользоваться статическим методом GetEventLogs. Как известно, в PowerShell статические методы указываются после двойного знака двоеточия - ::
[Administrator] [System.Diagnostics.EventLog]::GetEventLogs("dc1") Max(K) Retain OverflowAction Entries Name ------ ------ -------------- ------- ---- 16 384 0 OverwriteAsNeeded 289 Application 512 0 OverwriteAsNeeded 45 Directory Service 512 7 OverwriteOlder 10 DNS Server 512 0 OverwriteAsNeeded 52 File Replication Service 131 072 0 OverwriteAsNeeded 12 369 Security 16 384 0 OverwriteAsNeeded 498 System 15 360 0 OverwriteAsNeeded 625 Windows PowerShell [Administrator]
При этом обратите внимание на аргумент в скобках - в них можно указывать имена удалённых компьютеров для получения списка журналов с них. В данном случае я посмотрел список журналов на контроллере домена. Чтобы получить события из журнала нужно создать объект класса System.Diagnostics.Eventlog:
New-Object System.Diagnostics.Eventlog("Application","dc1")
В скобках первым аргументом указывается имя жрунала, а вторым аргументом - имя компьютера. Если имя не будет указано, то будет использоваться локальный компьютер:
[Administrator] $EventLog = new-Object System.Diagnostics.Eventlog("Application","dc1") [Administrator] $EventLog | gm -MemberType property TypeName: System.Diagnostics.EventLog Name MemberType Definition ---- ---------- ---------- Container Property System.ComponentModel.IContainer Container {get;} EnableRaisingEvents Property System.Boolean EnableRaisingEvents {get;set;} Entries Property System.Diagnostics.EventLogEntryCollection Entries {get;} Log Property System.String Log {get;set;} LogDisplayName Property System.String LogDisplayName {get;} MachineName Property System.String MachineName {get;set;} MaximumKilobytes Property System.Int64 MaximumKilobytes {get;set;} MinimumRetentionDays Property System.Int32 MinimumRetentionDays {get;} OverflowAction Property System.Diagnostics.OverflowAction OverflowAction {get;} Site Property System.ComponentModel.ISite Site {get;set;} Source Property System.String Source {get;set;} SynchronizingObject Property System.ComponentModel.ISynchronizeInvoke SynchronizingObject {get;set;} [Administrator]
Заодно мы и посмотрели свойства полученного объекта. Для получения списка логов нужно воспользоваться свойством Entries:
[Administrator] $EventLog.Entries | select -last 5 Index Time Type Source EventID Message ----- ---- ---- ------ ------- ------- 285 Nov 29 21:05 Info SceCli 1704 Security policy in the Group policy objects has been applied ... 286 Nov 29 21:35 Info SceCli 1704 Security policy in the Group policy objects has been applied ... 287 Nov 29 21:40 Info SceCli 1704 Security policy in the Group policy objects has been applied ... 288 Nov 29 21:43 Info SceCli 1704 Security policy in the Group policy objects has been applied ... 289 Dec 08 20:19 Info SceCli 1704 Security policy in the Group policy objects has been applied ... [Administrator]
Кстати говоря, если посмотреть вывод команды Get-Eventlog, то он будет идентичный. Т.е. можно смело предположить, что командлет Get-Eventlog использует именно механизмы .NET. А теперь попробуем рассмотреть статические методы данного класса:
[Administrator] $EventLog | gm -MemberType methods -Static TypeName: System.Diagnostics.EventLog Name MemberType Definition ---- ---------- ---------- CreateEventSource Method static System.Void CreateEventSource(String source, String logName), static System.... Delete Method static System.Void Delete(String logName), static System.Void Delete(String logName... DeleteEventSource Method static System.Void DeleteEventSource(String source), static System.Void DeleteEvent... Equals Method static System.Boolean Equals(Object objA, Object objB) Exists Method static System.Boolean Exists(String logName), static System.Boolean Exists(String l... GetEventLogs Method static System.Diagnostics.EventLog[] GetEventLogs(), static System.Diagnostics.Even... LogNameFromSourceName Method static System.String LogNameFromSourceName(String source, String machineName) ReferenceEquals Method static System.Boolean ReferenceEquals(Object objA, Object objB) SourceExists Method static System.Boolean SourceExists(String source), static System.Boolean SourceExis... WriteEntry Method static System.Void WriteEntry(String source, String message), static System.Void Wr... WriteEvent Method static System.Void WriteEvent(String source, EventInstance instance, Params Object[... [Administrator]
Первый метод, CreateEventSource позволяет создать свой источник событий в эвентлоге. А так же свой журнал:
[Administrator] [System.Diagnostics.EventLog]::CreateEventSource("MySource", "PowerShell CustomLog", "dc1") [Administrator] [System.Diagnostics.EventLog]::GetEventLogs("dc1") Max(K) Retain OverflowAction Entries Name ------ ------ -------------- ------- ---- 16 384 0 OverwriteAsNeeded 289 Application 512 0 OverwriteAsNeeded 45 Directory Service 512 7 OverwriteOlder 10 DNS Server 512 0 OverwriteAsNeeded 52 File Replication Service 512 7 OverwriteOlder 0 PowerShell CustomLog 131 072 0 OverwriteAsNeeded 12 369 Security 16 384 0 OverwriteAsNeeded 498 System 15 360 0 OverwriteAsNeeded 625 Windows PowerShell [Administrator]
Вот так очень просто мы создали собственный источник событий (здесь не отображён) и свой собственный журнал событий! Причём, всё так же удалённо! Для удаления журнала и источника события необходимо использовать статические методы DeleteEventSource и Delete:
[System.Diagnostics.EventLog]::Delete("LogName") [System.Diagnostics.EventLog]::DeleteEventSource("SourceName")
Чтобы управлять размером журнала нужно использовать свойство MaximumKilobytes. Увеличим размер журнала PowerShell CustomLog с 512 килобайт до 2-х мегабайт:
[Administrator] $EventLog = new-Object System.Diagnostics.Eventlog("PowerShell CustomLog","dc1") [Administrator] $EventLog.MaximumKilobytes = 2048 [Administrator] [System.Diagnostics.EventLog]::GetEventLogs("dc1") Max(K) Retain OverflowAction Entries Name ------ ------ -------------- ------- ---- 16 384 0 OverwriteAsNeeded 289 Application 512 0 OverwriteAsNeeded 45 Directory Service 512 7 OverwriteOlder 10 DNS Server 512 0 OverwriteAsNeeded 52 File Replication Service 2 048 7 OverwriteOlder 0 PowerShell CustomLog 131 072 0 OverwriteAsNeeded 12 369 Security 16 384 0 OverwriteAsNeeded 498 System 15 360 0 OverwriteAsNeeded 625 Windows PowerShell
Если сравнить 2 последних вывода, то заметим, что размер действительной изменился. Давайте запишем какое-нибудь событие в журнал. Для этого воспользуемся методом WriteEntry:
[Administrator] $EventLog.Source = "MySource" [Administrator] $EventLog.WriteEntry("Hello World!", "Information") [Administrator] $EventLog = new-Object System.Diagnostics.Eventlog("PowerShell CustomLog","dc1") [Administrator] $EventLog.entries Index Time Type Source EventID Message ----- ---- ---- ------ ------- ------- 1 Dec 08 22:55 Info MySource 0 Hello World! [Administrator]
Сперва мы указали источник события, потом применили метод WriteEntry, где ввели текст и тип события. Последней строкой мы убедились, что событие успешно записалось! Что касается типа события, то тут самому особо придумать ничего нельзя, потому что список типов жёстко регулируется:
[Administrator] [enum]::GetNames([System.Diagnostics.EventLogEntryType]) Error Warning Information SuccessAudit FailureAudit [Administrator]
Чтобы очистить журнал от событий нужно использовать метод Clear:
$EventLog = New-Object System.Diagnostics.Eventlog("PowerShell CustomLog","dc1") $EventLog.Clear()
И напоследок расскажу о действии при заполнении журнала. Для этого используется метод ModifyOverflowPolicy и метод может иметь следующие свойства:
Эти свойства, думаю, в представлении не нуждаются, поэтому покажу примеры их использования:
$EventLog = New-Object System.Diagnostics.Eventlog("PowerShell CustomLog","dc1") $EventLog.ModifyOverflowPolicy("OverwriteAsNeeded",$null) $EventLog.ModifyOverflowPolicy("DoNotOverwrite",$null) $EventLog.ModifyOverflowPolicy("OverwriteOlder",14)
К сожалению, средствами .NET невозможно архивировать журналы собитий, как это я описывал в предыдущей статье. Вот, вроде рассказал всё, что мне казалось интересным по этой теме. В следующий раз расскажу об управлении эвентлогом средствами WMI.
Comments: