Перейти на главную страничку сайта (список статей, файлы для скачивания)

ФОРУМ (здесь можно обсудить эту статью, а также любые проблемы программирования на различных макроязыках и в скриптовых средах)

Рецепты Windows Scripting: мониторинг состояния служб

Автор статьи - Александр Нагаев, г. Москва


В этой статье я расскажу, как можно мониторить состояние запущенных сервисов, автоматически запуская их при непредвиденной остановке и отсылая при этом по почте сообщение. Для того, чтобы наш скрипт работал как служба, т.е. работал и после выхода из системы, будем использовать бесплатную программку из Resource Kit: Autoexnt.exe - AutoExNT Service. Если есть некая служба или несколько служб, и они не должны по каким-то причинам внезапно останавливаться, а в момент запуска необходимо сделать ещё несколько каких-то операций, то стандартных средств восстановления служб в Windows XP/2003 будет недостаточно.

Воспользуемся возможностями технологии WMI. Описывать эту технологию я здесь не буду, но на этом сайте вы можете найти краткие описания, например эту статью. Также вы можете купить хорошую книгу "Администрирование Windows с помощью WMI и WMIC" (Попов А.В., Шикин Е.А.).

Скрипт состоит из основного тела и двух процедур.

Основное тело выглядит следующим образом:

Dim objSink, fso, LogFile, objService, rComp, Service1, Service2
'Ваш компьютер
rComp = "." 
'Ваши две любые службы
Service1 = "Themes" 'Темы
Service2 = "Spooler" 'Служба печати
Set objSink = WScript.CreateObject("WbemScripting.SWbemSink","SINK_")
'Создаём объект для работы с файловой системой
Set fso = Wscript.CreateObject("Scripting.FileSystemObject")
'Открываем файл для записи и создаём его, если его не существует
Set LogFile = fso.OpenTextFile("C:\immSrvASNC.Log", 8, True)
'Подключаемся к пространству имён на машине rComp
Set objService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & rComp & "\root\cimv2")
'Временный фильтр на события с опросам каждые 15 секунд  
objService.ExecNotificationQueryAsync objSink, _
"Select * From __InstanceModificationEvent Within 15 Where TargetInstance ISA 'Win32_Service'"
'Задержка 1 секунда
Do 
    WScript.Sleep 1000
Loop

Следующим этапом является обработчик событий:

Sub SINK_OnObjectReady(objLatestEvent, objAsyncContext)
    Dim xDate
    If LCase(objLatestEvent.TargetInstance.Name) = LCase(Service1) Then
        If objLatestEvent.TargetInstance.State = "Stopped" Then
            xDate = Date & "   " & Time
            tcValue = objLatestEvent.TargetInstance.StartService
            Call sendMessage(tcValue, xDate, Service1)
        End If
    Elseif LCase(objLatestEvent.TargetInstance.Name) = LCase(Service2) Then
        If objLatestEvent.TargetInstance.State = "Stopped" Then
            xDate = Date & "   " & Time
            tcValue = objLatestEvent.TargetInstance.StartService
            Call sendMessage(tcValue, xDate, Service2)
        End If
    End If
End Sub

И, наконец, пошлём письма, если сервисы грохнутся:

Sub sendMessage(runState, xDate, Named)
    On Error Resume Next
    Dim tempStr, objMessage, WshNetwork
    Set objMessage = CreateObject("CDO.Message")
    Set WshNetwork = WScript.CreateObject("WScript.Network")
    'Проверка состояния сервисов
    Select Case runState
        Case 0
            tempStr = "был успешно запущен."
        Case Else
            tempStr = "запуск этого сервиса невозможен."
    End Select
    'Создание сообщения
    objMessage.To = "myEmail@mail.ru"
    objMessage.From = WshNetwork.ComputerName & "@ourdomain.ru"
    objMessage.Subject = "Automessage from " & WshNetwork.ComputerName
    objMessage.TextBody = xDate & " cервис " & Named & " перешёл в состояние СТОП." & _
    VbCrLf & Date & "   " & Time & " " & tempStr
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
    "ourdomain.ru"
    objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = _
    25
    objMessage.Configuration.Fields.Update
    objMessage.Send
    If Err.Number <> 0 Then
        LogFile.WriteLine "Отправка письма невозможна по причине: " & Err.Description
        Err.Clear
    End If
    LogFile.WriteLine xDate & " cервис " & Named & " перешёл в состояние СТОП." & _
    VbCrLf & Date & "   " & Time & " " & tempStr
    LogFile.WriteLine
    Set objMessage = Nothing
    Set WshNetwork = Nothing    
End Sub

В строке скрипта

objMessage.To = "myEmail@mail.ru"

исправьте myEmail@mail.ru на свой e-mail.


В строке скрипта

objMessage.Configuration.Fields.Item("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _
"ourdomain.ru"

исправьте ourdomain.ru на ваш smtp сервер, например, mail.ourdomain.ru.


Теперь можно сохранить скрипт как test.vbs на диске c:\ (обратите внимание на название, так как оно прописано в AutoExNt.bat). Если хотите сохранить в другом месте, то нужно подправить AutoExNt.bat. Теперь тестируем: просто запускаем скрипт, а затем пробуем остановить службы печати и «Темы», обновляем и видим, что службы снова запущены, а письма отосланы (если установлен SMTP, а он есть в компонентах Windows вместе с IIS) и появились записи в файле журнала на диске С:\immSrvASNC.Log.

На этом не остановимся и создадим bat-файл следующего содержания:

@echo off
cscript.exe "C:\test.vbs"

Сохраним под именем AutoExNt.bat. Теперь нужно провернуть такой финт: копируем этот файл и файлы из Resource Kit (autoexnt.exe, instexnt.exe, servmess.dll) в директорию %WinDir%\system32\. Фишка в том, что autoexnt.exe запускает AutoExNt.bat как сервис… Ну и соответственно процесс cscript.exe.

Не надо забывать про права на запуск сервисов, а также на подключение к пространству имён. И вообще, лучше быть админом компа, как минимум.

Теперь проинсталлируем сервис AutoExNt.exe. В командном окне или в батнике напишем:

instexnt install

Запустим сервис AutoExNt, соответственно запустится и скрипт. Можно разлогиниваться и быть уверенным, что мониторинг продолжается. Сервис AutoExNt через несколько минут сам остановится, но скрипт будет прекрасно продолжать работать и оставаться в процессах. Так что не обращайте на этот сервис внимания. Для полной остановки нужно уничтожить процесс cscript.exe.

На этом всё. Кому интересно – попробуйте.

Все необходимые файлы для запуска этого примера вы можете скачать здесь (19 717 байт).

Перейти на главную страничку сайта (список статей, файлы для скачивания)

© 2007 http://www.script-coding.com При любом использовании материалов сайта обязательна ссылка на него как на источник информации, а также сохранение целостности и авторства материалов.