Управляем службами Windows с помощью PowerShell

от автора


Начинаем серию переводов, посвященную управлению службами Windows с помощью PowerShell 2.0 и 3.0.
В данном посте будут рассмотрены следующие вопросы управления службами Windows:

  • Получаем статус службы на локальном компьютере
  • Получаем статус службы на удаленном компьютере
  • Осуществляем фильтрацию служб (например, остановленные службы)
  • Зависимые службы


Обозначим начальные условия: Вы работаете под Windows 7 и выше и у Вас имеются права администратора. Все команды рекомендуются выполнять в лабораторной или виртуальной среде, перед тем, как применять в “полевых условиях”.

ПОЛУЧАЕМ СТАТУС СЛУЖБЫ

Давайте начнем с того, что просто получим статус всех служб, запущенных на локальном компьютере. Используем для этого командлет Get-Service.

PS C:\> get-service 

PowerShell, как правило, не чувствителен к регистру. Вывод приведен на скриншоте ниже.

image

Каждая строка представляет собой объект службы (service object).Каждый сервисный объект, как правило, имеет свои свойства. Вы можете открыть их, просто передав эти объекты в другую команду, Get-Member.

PS C:\> get-service | get-member 

Результаты приведены на скриншоте ниже.

image

Параметр Typename сверху говорит о том, что за объект перед нами; в данном случае это System.ServiceProcess.ServiceController. На скриншоте также обведены свойства объекта. Это атрибуты, которые описывают этот тип объекта. Хотя большинство из них не используются при отображении по умолчанию, вы можете использовать их, если вы их знаете.
Например, нам интересно посмотреть информацию только о Windows Update. Через Get-Service получим информацию только о некоторых ее свойствах.

PS C:\> get-service wuauserv | select Displayname,Status,Can* DisplayName : Windows Update Status : Stopped CanPauseAndContinue : False CanShutdown : False CanStop : False  

Как я узнал, что могу напечатать имя службы? Посмотрел с помощью Get-Service.
PS C:\> help get-service

image

Вы можете получить полную справочную информацию, напечатав:

PS C:\> help get-service –full 

Информацию о службе можно получить по ее имени или даже начальным буквам имени.

PS C:\> get-service wi* Status Name DisplayName ------ ---- ----------- Stopped WiaRpc Still Image Acquisition Events Running WinDefend Windows Defender Service Running WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se... Running Winmgmt Windows Management Instrumentation Running WinRM Windows Remote Management (WS-Manag... 

Или если вам удобнее работать с отображаемыми именами, используйте параметр –Displayname.

PS C:\> get-service -DisplayName "windows a*" Status Name DisplayName ------ ---- ----------- Stopped AllUserInstallA... Windows All-User Install Agent Running AudioEndpointBu... Windows Audio Endpoint Builder Running Audiosrv Windows Audio  

Я должен использовать имя параметра, чтобы PowerShell воспринимал значения в качестве отображаемого имени, а не фактического имени службы. Команда будет выглядеть так:

PS C:\> get-service "windows a*"  

Параметр –Name можно не печатать.

ПОЛУЧАЕМ СТАТУС СЛУЖБЫ НА УДАЛЕННЫХ КОМПЬЮТЕРАХ

До этого нас интересовало получение информации о статусе служб на локальном компьютере. Однако управление службами осуществляется на удаленных компьютерах. Если посмотреть справку по Get-Service, то можно увидеть наличие у этого командлета параметра –Computername. В данном случае подключение к удаленным компьютерам осуществляется без включения функции удаленного управления PowerShell. Если вы можете управлять службами, используя инструменты командной строки (sc.exe или консоль управления Service Manager), вы можете использовать PowerShell. Давайте взглянем на пример:

PS C:\> get-service spooler -ComputerName novo8 Status Name DisplayName ------ ---- ----------- Running spooler Print Spooler 

Любая команда, которую я демонстрировал, можно использовать для передачи удаленному компьютеру. Даже нескольким компьютерам, если у вас есть соответствующие права на удаленном компьютере. Если вы используете PowerShell v3, то можно легко выбрать одну службу на множестве компьютеров.

PS C:\> get-service wuauserv -ComputerName chi-dc01,chi-dc02,chi-dc03 Status Name DisplayName ------ ---- ----------- Running wuauserv Windows Update Stopped wuauserv Windows Update Running wuauserv Windows Update 

Для наглядности представления отформатируем вывод.

PS C:\> get-service wuauserv -ComputerName chi-dc01,chi-dc02,chi-dc03 | format-table Name,Status,Machinename -autosize Name Status MachineName ---- ------ ----------- wuauserv Running chi-dc03 wuauserv Stopped chi-dc02 wuauserv Running chi-dc01  

Тот же самый результат, но в PowerShell v2.

PS C:\> 'chi-dc01','chi-dc02','chi-dc03'| foreach {get-service wuauserv -computername $_} | Format-Table Name,Status,Machinename -AutoSize Name Status MachineName ---- ------ ----------- wuauserv Running chi-dc01 wuauserv Stopped chi-dc02 wuauserv Running chi-dc03  

ОСУЩЕСТВЛЯЕМ ФИЛЬТРАЦИЮ (ИСПОЛЬЗУЯ WHERE-OBJECT)

Фильтрация служб осуществляется с помощью командлета Where-Object (where – сокращение для командлета). Все, что нам нужно от PowerShell в этом случае, так это получить только те службы, у которых статус равен “stopped”.

PS C:\> get-service | where {$_.status -eq 'stopped'} 

PowerShell получает информацию обо всех службах и передает их (с помощью “|”) в следующую команду, которая осуществляет просмотр каждого объекта. Если свойство статуса объекта равно “stopped”, она остается в конвейере (pipeline), в противном случае она из него исключается. В конце выражение PowerShell отображает те объекты, которые остались в конвейере.
Результаты приведены ниже.

image

Теперь давайте попробуем найти одну службу на нескольких машинах. Вывод отформатируем в таблицу.

PS C:\> get-service -computername @('chi-dc01','chi-dc02','chi-dc03') | where {$_.name -eq 'wuauserv'} | format-table Name,Status,Machinename -autosize Name Status MachineName ---- ------ ----------- wuauserv Running chi-dc02 wuauserv Running chi-dc01 wuauserv Running chi-dc03 

Мы даже можем комбинировать запрос отдельных служб с их фильтрацией.

PS C:\> get-service "win*" -comp chi-dc03 | where {$_.status -eq 'running'} Status Name DisplayName ------ ---- ----------- Running Winmgmt Windows Management Instrumentation Running WinRM Windows Remote Management (WS-Manag... 

Эта команда находит все службы на компьютере CHI-DC03, которые начинаются с ‘WIN’, но отображает только те, которые запущены.
Также можно сгруппировать объекты по свойству статуса (status property).

PS C:\> $dc03 = get-service -computername chi-dc03 | Group-Object -Property Status 

Переменная $dc03 является объектом GroupInfo.

PS C:\> $dc03 Count Name Group ----- ---- ----- 64 Running {System.ServiceProcess.ServiceController, Sy... 79 Stopped {System.ServiceProcess.ServiceController, Sy... 

Свойство Group представляет собой коллекцию связанных служб.

PS C:\> $dc03.Get(0).group 

Написанное выше проще понять, если взглянуть на скриншот.

image

Что касается меня, то я бы предпочел использовать хеш-таблицу.

PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status -AsHashTable PS C:\> $hash Name Value ---- ----- Running {System.ServiceProcess.ServiceController, Sys... Stopped {System.ServiceProcess.ServiceController, Sys... 

Теперь каждое имя представляет собой свойство в хеш-таблице. Если у вас имеется опыт работы с PoweShell, вы, возможно, подумываете сделать сделующее:

PS C:\> $hash.running.count 

Однако ничего не произойдет. Потому что свойство Status является просто перечислением (enumeration) для [System.ServiceProcess.ServiceControllerStatus] .NET клас и такие свойства, как Running и Stopped представляют собой целые числа. PowerShell осуществляет конвертацию, чтобы представить в более наглядной форме.

PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status –AsHashTable –AsString 

В чем суть параметра –AsString, на мой взгляд, достаточно очевидно. Теперь работать с хеш-таблицей стало проще.

PS C:\> $hash.running.count 62 PS C:\> $hash.running[0..3] Status Name DisplayName ------ ---- ----------- Running ADWS Active Directory Web Services Running AppHostSvc Application Host Helper Service Running BFE Base Filtering Engine Running BrokerInfrastru... Background Tasks Infrastructure Ser... 

Следующей задачей на повестке дня является проверка зависимостей сервера (server dependencies).

Требуемые службы

PowerShell позволяет просто получить статус всех служб, которые требуется для данной службы, даже на удаленном компьютере.

PS C:\> get-service dns -ComputerName chi-dc03 –RequiredServices Status Name DisplayName ------ ---- ----------- Running Afd Ancillary Function Driver for Winsock Running Tcpip TCP/IP Protocol Driver Running RpcSs Remote Procedure Call (RPC) Running NTDS Active Directory Domain Services 

Параметр –RequiredServices передаст объект в конвейер для каждой требуемой службы. Вы можете даже пойти дальше и проверить требуемые службы для работы данной службы.

PS C:\> get-service dns -ComputerName chi-dc03 -RequiredServices | select name,@{name="computername";expression={$_.machinename}} | get-service -RequiredServices Status Name DisplayName ------ ---- ----------- Running RpcEptMapper RPC Endpoint Mapper Running DcomLaunch DCOM Server Process Launcher 

Параметр –Computername командлета Get-Service возьмет вывод, но только для тех объектов, у которых есть объект свойство Computername – именно поэтому я использую хеш-таблицу с Select-Object. Как мы видим проблем со службой DNS на компьютере CHI-DC03 нет.

ЗАВИСИМЫЕ СЛУЖБЫ

Мы можем сделать то же самое с зависимыми службами. Если таковых не имеется, в конвейер ничего передано не будет.

PS C:\> get-service dns -ComputerName chi-dc03 -DependentServices PS C:\> get-service lanmanworkstation -ComputerName chi-dc03 -DependentServices Status Name DisplayName ------ ---- ----------- Stopped SessionEnv Remote Desktop Configuration Running Netlogon Netlogon Running Dfs DFS Namespace Running Browser Computer Browser  

Требуемые и зависимые службы также являются частью каждого объекта службы.

PS C:\> get-service rpcss | Select *services RequiredServices DependentServices ---------------- ----------------- {RpcEptMapper, DcomLaunch} {WwanSvc, wuauserv, WSearch, wscsvc...} 

А пока Вы можете получить все зависимости для всех служб, следующая команда

PS C:\> get-service –DependentServices 

Это не даст вам особо полезную информацию, поэтому я рекомендую осуществлять запрос по конкретным службам. Команда работает гораздо лучше PowerShell v3.

PS C:\> get-service dns -comp chi-dc01,chi-dc03 -RequiredServices | Sort Machinename,Name | Format-table -GroupBy machinename 

Результаты видны на скриншоте ниже.

image

Чтобы получить подобные результаты в PowerShell v2, вам придется передать имена компьютеров (computernames) в Get-Service.

PS C:\> "chi-dc01","chi-dc03" | foreach { get-service dns -comp $_ -RequiredServices} | Sort Machinename,Name | format-table -GroupBy machinename 

В следующей статье будет рассмотрен запуск, остановка и перезапуск служб.
Конец перевода.

P.S. Хотим также поделиться нашей бесплатной программой для управления службами Windows – NetWrix Service Monitor. Программа отслеживает все автоматически запускаемые службы на группе серверов и в случае внезапного сбоя одной или нескольких из них отправляет уведомления по электронной почте. Функция перезапуска гарантирует, что все подконтрольные службы будут работать без простоев. Программа проста в настройке: устанавливаем, вводим имена компьютеров и указываем нужный адрес электронной почты.

ссылка на оригинал статьи http://habrahabr.ru/company/netwrix/blog/166289/


Комментарии

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *