17 июня 2009

В продолжение темы мониторинга

В предыдущем посте мы тестировали exchange hub-cas сервера на предмет доступности всех сервисов, с тех пор утекло много-много воды. На этот раз я хочу предложить решение еще ряда проблем.
1. Мониторинг свободного дискового пространства на жестких дисках.
2. Оповещение всех причастных лиц.
3. Удобный лог.

Решение проблемы 1.

При помощи одного запроса к WMI мы можем получить все текущие свойства дисковых устройств нашей машины.
Поможет нам следующий запрос


$obj = (gwmi -query "select * from win32_logicaldisk where FileSystem = 'NTFS' ")

Тут мы получаем все свойства дисков где файловая система = NTFS. Почему так? Потому что в некоторых машинах будут CD, свободное место в которых нам знать не нужно.

Далее создается тривиальный в общем-то цикл

foreach ($disk in $obj) {
$freespace = ($disk.freespace / $gb);
$totalspace = ($disk.Size / $gb);
$freepercent = (($freespace / $totalspace)*100);


* переменная $gb = 1024 * 1024 * 1024

Так мы получаем все необходимые данные. Объем свободного места, общий объем диска, процент свободного места.


Решение проблемы 2.

Далее следует условие, в котором указывается что if ($freepercent -lt "30") {

послать сообщение функцией sndem которую я все-таки когда-нибудь тоже здесь выложу =)

Тут есть одна хитрость. У функции sndem есть три параметра

function sndem {
param($Title,$Body, $serv)


С первыми двумя все понятно, третий - имя сервера которое будет подставлено в параметр $From = "$serv " Откуда берется имя сервера я расскажу в следующей части.

Так вот функцию надо вызывать следующим образом:

$sdf = "На диске "+$disk.DeviceID+" сервера "+$hon+" свободно только "+$freespace+" gb из "+$totalspace+" gb! Надо что-то делать!"
sndem "Free space less 30%" $sdf $hon


Тут необходимо небольшое пояснение, какая переменная откуда взялась.

$disk.DeviceID - буква диска, мы ее получили запросив через WMI все свойства класса win32_logicaldisk

$hon - помните про имя хоста? самй простой способ его получить присвоить переменной значение env:ComputerName

Значения переменных $freespace и $totalspace приведены выше.


Ну и собственно предлагаю вам посмотреть код:

function sndem {
param($Title,$Body, $serv)
$SmtpClient = new-object system.net.mail.smtpClient
$SmtpServer = "smtp.contoso.com"
$SmtpClient.Host = $SmtpServer
$To = "admin@contoso.com"
$From = "$serv "
$SmtpClient.Send($from,$to,$title,$Body)
}

[string] $hon = $env:COMPUTERNAME;
$gb = 1024 * 1024 * 1024;
$obj = (gwmi -query "select * from win32_logicaldisk where FileSystem = 'NTFS' ") ;
foreach ($disk in $obj) {
$freespace = ($disk.freespace / $gb);
$totalspace = ($disk.Size / $gb);
$freepercent = (($freespace / $totalspace)*100);
if ($freepercent -lt "30") {
$sdf = "На диске "+$disk.DeviceID+" сервера "+$hon+" свободно только "+$freespace+" gb из "+$totalspace+" gb! Надо что-то делать!"
sndem "Free space less 30%" $sdf $hon
}
}


Ну и наконец решение проблемы 3.

Записать все в удобный лог-файл. В качестве такового был выбран SQL сервер. Сохранив там данные впоследствии можно будет на их основе построить графики, посмотреть динамику роста, ну и вообще, возможность писать в базу данных скриптом фишка прикольная.

Писать в базу SQL достаточно просто вот функция

function wrtodb ($hname, $free, $total, $devid) {
#получаем текущую дату-время
$date = Get-Date
#создаем подключение
$conn = New-Object System.Data.SqlClient.SqlConnection
$connString = "server=localhost;database=monitor;Integrated Security = SSPI"
$conn.ConnectionString = $connString
$conn.Open()
#создаем команду для добавления данных в таблицу
$query = "INSERT INTO [monitor].[dbo].[HardDisk] ([HostName], [DiskID],[FreeSpace],[TimeStamp],[AllSpace]) VALUES ('$hname', '$devid',$free,'$date',$total)"
$cmd = $conn.CreateCommand()
$cmd.CommandText = $query
#и выполняем ее
$cmd.ExecuteNonQuery()
#не забываем закрыть подключение к бд =)
$conn.Close
}



Функция должна вызываться каждый раз когда скрипт получает все данные.
Поэтому помещаем ее в конец петли foreach ($disk in $obj) перед проверкой, посылать письмо или нет.

пример вызова функции wrtodb:

wrtodb $hon $freespace $totalspace $disk.DeviceID


Ну вот в общем-то и все=)