PowerShell и LogParser в помощь вебмастеру

Опубликовано 30.08.2008 13:00:00
Основная прелесть скриптов PowerShell - возможность сочетать в одном месте использование встроенных скриптлетов, объектов .NET, WMI, Windows Script Host и вывода консольных программ. Это не только расширяет область применения консоли PowerShell, но и расширяет аудиторию, которая ей может быстро и безболезненно может начать пользоваться.

Кто такой веб-мастер? Человек, вынужденный совмещать навыки как минимум программиста, верстальщика и администратора. В такой ситуации времени на изучение средств для написания системных скриптов (WMI, WSH) постоянно не хватает. В то время как получать сводки с информацией о функционировании системы необходимо. И вот, теперь мы имеем PowerShell. Посмотрим, как построить простейшую систему мониторинга с его помощью: свободное место на дисках, избранные события eventlog, ошибки в логах IIS. Так как полученный отчет нужно будет отправить по электронной почте, результат мы будем сохранять в текстовую переменную $m.

Со свободным местом на дисках все предельно просто. Получаем объект, представляющий диск и вызываем свойство этого объекта AvailableFreeSpace. Так как свойство возвращает размер в байтах, результат не мешало бы отформатировать: перевести в гигабайты и уменьшить количество разрядов после запятой.
$c = [System.IO.DriveInfo]::getdrives() | where-object {$_.Name -match "C:"}
$m += "Disk C:\ free space: " + ("{0:N3}" -f ($c.AvailableFreeSpace/1073741824)) + "GB`n
Работа с Event Log возможна несколькими способами: как при помощи методов PowerShell, так и при помощи LogParser. Так как использование PowerShell несколько упрощает задачу, я выбрал его. 

События Windows хранятся в трех основных логах: Application, System, Security. Каждое событие Event Log обладает некоторами свойствами, на основе которых эти события можно фильтровать. Для начала возьмемся за лог Application. Этот лог доступен на чтение/запись даже от непривилегированных аккаунтов, и предназначен для хранения событий прикладных программ, в том числе тех, которые могут заинтересовать вебмастера: SQL Server, .NET Framework (события ASP.NET). Понятно, что при таком разнообразии сложно заранее определить какие события нас могут заинтересовать. Поэтому методом изучения лога потребуется убрать из отчета все более-менее периодичные события, которые нас не интересуют. Наиболее удобный метод фильтрации в этом случае - на основе Event ID. Информацию о значениях событий с определенными ID можно получить на сайте EventID.net.
$m += "Application events:"
$m += get-eventlog Application | Where-Object { (1111, 2222, 3333) -notcontains $_.EventID } | Where-object {$_.TimeGenerated -gt (Get-date).AddHours(-12)} | Format-List EntryType,TimeGenerated,Message | Out-String
Данная строка говорит сама за себя, я бы хотел заострить внимание на одной из очень полезных команд PowerShell, предназначенных для форматирования. Так как каждая команда PowerShell, в отличие от своих Unix-предшественников возвращает не текстовую строку, а объект, это значительно упрощает дальнейшую обработку результатов этих команд. В данном случае мы получаем набор объектов, каждый из которых представляет собой событие EventLog, и обладает некоторыми свойствами. Нам требуются не все свойства этих объектов, к тому же, нам нужен более удобный для отображения в письме формат, поэтому мы используем команду Format-List и указываем, какие свойства нужно отображать. Полученный список все еще является объектом, поэтому его следует преобразовать в текст простым движением руки - командой Out-String.

Второй лог, который требуется обработать - лог аудита событий безопасности системы. Степень детализации этого лога зависит от настроек системы, и он может содержать огромную массу информации. Из всех событий этого лога можно выделить два типа событий, которые представляют особый интерес: события интерактивного входа в систему (через локальную консоль или посредством службы терминальных сервисов) и события ошибок аутентификации. Строго говоря, подобные события требуется мониторить в реальном времени, а не получать их в отчете пост-фактум, но во-первых подписка на события выходит за рамки данной статьи, а во-вторых, в отчете эта информация лишней также не будет.

Как и все события Event Log, события лога Security обладают свойством event id. В зависимости от версии Windows, ID для события определенного типа может быть различным. Например, события успешного входа в систему в Server 2003 имеют ID=528, в то время как то же событие в Server 2008 имеет ID=4624. Но фильтрации по Event ID в данном случае недостаточно, так как вход в систему (получение полномочий) бывает разных типов, их которых требуется отслеживать далеко не все. Ознакомиться с возможными типами получения полномочий в системе можно здесь, и решить, какие типы потребуется отслеживать вам. Обычно достаточно отслеживать события с Logon Type=10 (сетевой интерактивный вход в систему, например через Terminal services), Logon Type=2 (локальный вход). Так вот, в этом случае нам придется осуществлять фильтрацию на основе информации, которая находится в теле самого сообщения Event Log. Это можно делать с помощью регулярных выражений, а можно просто взять фиксированную строку из события, что я и сделал:
$m += "`nLogon events:"
$m += get-eventlog Security | Where-Object { $_.Message.Contains("Logon Type:	10") } | Where-Object { $_.Message.Contains("Logon Type:	2") } | Where-Object { $_.EventID -eq 528 } | Where-object {$_.TimeGenerated -gt (Get-date).AddHours(-12)} | format-list Message | Out-String$m += "`nSecurity failures:"
$m += get-eventlog Security | Where-Object {$_.EntryType -ne "Success audit"} | Where-object {$_.TimeGenerated -gt (Get-date).AddHours(-12)} | format-list TimeGenerated,Message | Out-String
Далее - лог событий системы. Здесь все предельно просто, смотрим все события, кроме тех, у которых EntryType не равен Information.
$m += "`nSystem events"$m += Get-EventLog System | Where-Object {$_.EntryType -ne "Information"} | Where-Object {$_.TimeGenerated -gt (Get-date).AddHours(-12)} | Format-List EntryType,TimeGenerated,Message | Out-String
Заключительный штрих - берем все интересующие нас события в логе веб-сервера. В этом нам поможет LogParser, с которым задача становится практически тривиальной. Самое сложное - отформатировать результат максимально удобным образом, чего я добился подбором параметров LogParser + команда Format-Table, от которой, если честно, я не ожидал такой прыти. Одно дело - форматировать вывод объектов-результатов команд PowerShell, другое дело - текстовый результат посторонних утилит.

Если у вас достаточно большое количество веб-сайтов в IIS (а скорее всего так и есть, если уж вы настраиваете мониторинг выделенного сервера), может понадобиться вывод ошибок не для всех сайтов, а только для основных. В этом случае для требуемых сайтов нужно задать префикс в имени веб-сайта, и по этому префиксу фильтровать. В примере префиксом является строка "main_".
$m += "Today IIS errors (500):`nTime  Sitename  Status	Visitor IP	User-agent	URL	Bytes sent	Referer`n"
$m += Logparser -q:ON -i:IISW3C -o:NAT -rtp:0 -spaceCol:OFF -headers:ON -minDateMod:(Get-Date -UFormat "%Y-%m-%d") "SELECT time,s-sitename,sc-status,c-ip,cs(User-agent),cs-uri-stem,cs-uri-query,sc-bytes,cs(Referer) FROM  WHERE sc-status>=400" | format-table | out-string
Отчет получен. Теперь его нужно отправить по электронной почту администратору. Если почтовый сервер уствновлен на той же машине и не требует авторизации при отправке с локалхоста, используя объекты .NET Framework это очень просто:
$sc = New-Object -TypeName System.Net.Mail.SmtpClient("localhost")
$sc.Send("maintenance@mail.com", "webmaster@mail.com", "System report", $m)
Приведенный пример далеко не полный и содержит много допущений. Однако в качестве стартовой точки для настройки мониторинга здоровья системы может сослужить свою службу.

systemreport.zip (888.00 bytes)

Метки: , ,

Подблог: Разработка

Комментарии

25.12.2008 22:26:15

Василий Микоров

Вот тут хорошая книга про Powershell http://blogs.technet.com/abeshkov/archive/2008/12/24/3172943.aspx

И главное на русском.

Василий Микоров

22.04.2009 16:29:29

Сергей Иванов

Класный доклад про IIS + Powershell.

http://www.techdays.ru/videos/1170.html

Сергей Иванов

Добавить комментарий


(Отображает Gravatar)

biuquote
  • Комментарий
  • Предпросмотр
Loading