В нашей среде есть несколько серверов (Windows Server 2012 R2), которые устанавливают обновления автоматически и после этого перезапускаются.
После перезапуска мы хотели бы проверить статус всех служб (Windows), для которых установлен автоматический запуск. Если служба не запустилась, сценарий попытается запустить службу 3 раза, и если все попытки завершатся неудачно, он должен отправить уведомление по электронной почте, чтобы мы могли проверить, что не так с этой службой на этом сервере.
Мне было интересно, существует ли уже простое решение, может быть, сценарий PowerShell?
Сервис> Свойства> Восстановление
Можно выбрать, что делать при первых трех сбоях, включая перезапуск службы или выполнение команды.
Здесь вы также можете использовать Запустить программу чтобы настроить сценарий, который перезапускает службу, очищает файл, отправляет вам уведомление и т. д. Я полностью поддерживаю сценарий NMS (Zabbix) или Powershell, но большую часть этого можно решить изначально, а GPO (если применимо к вашей среде) может иметь этот набор для всех необходимых служб / машин.
Powershell - отличный способ контролировать эти службы. Как ни странно, я только что читал об этом в блоге сегодня. Я попытаюсь связать скрипт, если найду его, но общая его суть будет такова:
1.) Найдите службы, которые настроены на автоматический запуск.
2.) Проверить состояние сервиса.
Хитрость в том, что
get-service
командлет не выводит никакого типа StartupType, поэтому вам придется использовать вместо него WMI-объект Win32_Service.
Foreach($Server in $ServerList){
Get-WmiObject -ComputerName $Server Win32_Service |
Where-Object {$_.StartMode -eq 'Auto' -AND $_.State -eq 'Stopped'}
}
Это должно дать вам список услуг, соответствующих вашим желаемым параметрам.
НОТЫ На этот счет есть пара замечаний:
1.) Я настоятельно рекомендую вам запустить этот сценарий через пару минут после запуска серверов как $ _. StartMode -eq 'Auto' будет включать службы, запускаемые сразу после загрузки, И те, которые настроены на автоматический запуск после задержки. .
2.) Будут услуги, которые будут возвращены через этот однострочник, мониторинг которых вам, вероятно, не важен. (Например, на моем ноутбуке служба под названием "TrustedInstaller" соответствовала этим критериям и была возвращена как остановленная: /) Так что вам, скорее всего, придется отфильтровать и их.
Я бы посоветовал вам изучить возможность получения NMS. Мы используем PRTG, и он хорошо работает. В нем вы можете создавать датчики, которые контролируют службы Windows с помощью WMI. Вы можете настроить датчик для отправки писем / сценариев запуска, если служба выйдет из строя.
PRTG имеет лицензию на датчики, но бесплатная версия дает вам 100, которых должно хватить для пары серверов (вам нужен один датчик для каждой службы для мониторинга)
Я нашел скрипт Powershell, который мне идеально подходит, мне просто нужно немного его настроить. Вот ссылка http://doitcloudy.blogspot.de/2014/07/scriptgesteuerter-neustart-von-windows.html (Немецкий, но сценарий внизу страницы полностью английский). Однако мне нужна помощь с этой частью (строки 130 и последующие):
foreach ($item in $report){
Write-Host "Starting Service " $item.Name " on server: " $item.Server -Foregroundcolor yellow
$start = Get-Date
$startSVCblock = {param($item) Start-Service -InputObject (Get-Service -ComputerName $item.Server -Name $item.Name)}
$j = Start-Job -ScriptBlock $startSVCblock -Arg $item
do {
if ($j.State -ne 'Running') { break}
$j | Receive-Job
} while (((Get-Date) - $start) -le $timeout)
}
Я вижу, что именно здесь сценарий запускает службу, но я не привык к заданиям в Powershell. Как мне отредактировать сценарий, чтобы при сбое запуска службы он записывал имя службы в файл журнала? Может быть, с помощью try / catch?
Редактировать:
Если кто-то наткнется на это и захочет узнать, как я это решил: после долгих исследований я обнаружил, что очень сложно записать вывод Receive-Job в файл журнала. Поэтому я выбрал другой подход: проверяю, запущен ли сервер после завершения задания. Вот код:
foreach ($item in $report){
Write-Output "Starting Service " $item.Name " on server: " $item.Server
$start = Get-Date
$startSVCblock = {param($item) Start-Service -InputObject (Get-Service -ComputerName $item.Server -Name $item.Name)}
$j = Start-Job -ScriptBlock $startSVCblock -Arg $item
do {
if ($j.State -ne 'Running') { break}
$j | Receive-Job
} while (((Get-Date) - $start) -le $timeout)
$newService = Get-Service -ComputerName $item.Server -Name $item.Name
if ($newService.Status -ne "Running") { LogWrite "$item could not start" }
}