Май 112012
 
PowerShell

Продолжаю цикл статей по работе с удаленными серверами. На этот раз речь пойдет о чтении журналов.
Признайтесь, как часто вы просматриваете события журналов в windows? Всякий раз забываем это делать. А что если нам на почту будут приходить письма с “ошибками” в журнале? Ведь прочитать почту всегда легче, чем заходить на сервер и читать там. Тем более, что если серверов у нас много. На помощь может прийти PowerShell. У него есть замечательная команда

Get-EventLog

Вот с ее помощью и будем анализировать журналы.
Предлагаю готовый скрипт, который необходимо повесить в шедуллер и запускать с интервалом раз в час ну или раз в сутки, кому как нравиться. Все пояснения в комментариях. Файл “server_all.txt” должен иметь структуру, как я описывал в предыдущей статье.

<# 
Скрипт для сбора "Ошибок" и "Предупреждений" из журнала "System" на удаленных серверах, указанных в файле $srv
за последний час, и отправка результата на почту admin@mycompany.com
-------------------
настройки:
см: AddHours(-1) - время за какой промежуток собирать
см: -LogName "System" -EntryType "Error" , "Warning" - журнал, и типы сообщений
настройки почты - см. в самом конце.
#>
 
cls
 
$srv = Get-Content "c:\[path]\server_all.txt"
 
$dt = Get-Date
 
$outHTML = ""
$outHTML += '<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">'
$outHTML += '<html>'
$outHTML += '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />'
$outHTML += '<h2 align="center">Отчет за ' + $dt.ToString('dd/MM/yyyy HH:mm') + '</h2>'
$outHTML += '<table width="100%" border="1" cellspacing="2" cellpadding="2"  align="center">'
$outHTML += '<tr><th>№</th><th>Date</th><th>Computer</th><th>Type</th><th>EventID</th><th>Source</th><th>User</th><th>Message</th></tr>'
 
$ok = 0
 
#Забиваем массивы с данными
foreach ($var in $srv) {
 
	# проверяем на комментарий, если есть в строке #- значит это комент. или пустую строку
	if (($var -notmatch "#") -and ($var.Length -ne 0)){
 
		$out = $var -split ";"
 
		$password = $out[1] | ConvertTo-SecureString 
		$cred = New-Object System.Management.Automation.PSCredential $out[0],$password
 
		$s = $out[2] -split ","
		$session = New-PSSession -ComputerName $s -Credential $cred
 
		# выполняем запрос
		Invoke-Command -Session $session {$dtNow = Get-Date}
		Invoke-Command -Session $session {$dtPrev = $dtNow.AddHours(-1)}
		Invoke-Command -Session $session {$EventLog = get-eventlog -LogName "System" -EntryType "Error" , "Warning"}
		$result = Invoke-Command -Session $session {$EventLog | Where-Object {$_.TimeWritten -le $dtNow -and $_.TimeWritten -ge $dtPrev} }
 
		# Обработаем результат
		if ($result.Count -ge 0){
			$ok = 1
 
			for ($i=0; $i -lt $result.Count; $i++){
 
				$outHTML += '<tr align="left">'
				$outHTML += '<td>' + $i + '</td>'
				$outHTML += '<td>' + $result.SyncRoot[$i].TimeWritten + '&nbsp;</td>'
				$outHTML += '<td>' + $result.SyncRoot[$i].PSComputerName + '&nbsp;</td>'
 
				if ($result.SyncRoot[$i].EntryType -eq 'Error'){
					$outHTML += '<td bgcolor="#FF0000"><b>' + $result.SyncRoot[$i].EntryType + '</b>&nbsp;</td>'				
				}else{
					$outHTML += '<td bgcolor="#FFFF00"><b>' + $result.SyncRoot[$i].EntryType + '</b>&nbsp;</td>'				
				}
				$outHTML += '<td>' + $result.SyncRoot[$i].EventID + '&nbsp;</td>'
				$outHTML += '<td>' + $result.SyncRoot[$i].Source + '&nbsp;</td>'
				$outHTML += '<td>' + $result.SyncRoot[$i].UserName + '&nbsp;</td>'
				$outHTML += '<td>' + $result.SyncRoot[$i].Message + '&nbsp;</td>'
				$outHTML += '</tr>'
			}
		}
 
		#Выходим из сессии.
		Remove-PSSession -Session $session
	}
}
 
$outHTML += '</table></html>'
 
if ($ok -eq 1){
	# отправляем почту
	$SMTPClient          = new-object System.Net.Mail.SMTPClient 
	$Msg                 = new-object System.Net.Mail.MailMessage 
	$Msg.From            = "robot@mycompany.com" 
	$Msg.Subject         = '[Event Log] ' + $dt.ToString('dd/MM/yyyy HH:mm')
	$Msg.IsBodyHTML      = 1 
	$Msg.BodyEncoding    = [System.Text.Encoding]::UTF8
	$Msg.Body            = $outHTML
	$SMTPClient.Host     = 'host.mycompany.com' 
	$SMTPClient.Port     = 25 
	$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("robot@mycompany.com", "Pa$SWorD")
	$Msg.To.Add('admin@mycompany.com') 
	$SMTPClient.Send($Msg) 
}

В итоге на почту будет приходить письмо, примерно такого содержания:

Отчет за 11.05.2012 13:00

Date Computer Type EventID Source User Message
0 05/11/2012 13:00:04  server10  Error  56  TermDD    Описание ошибки.
1 05/11/2012 13:00:15  server3 Error  56  TermDD    Описание ошибки.

 Posted by at 18:13

Sorry, the comment form is closed at this time.