Начинаем серию переводов, посвященную управлению службами Windows с помощью PowerShell 2.0 и 3.0.
В данном посте будут рассмотрены следующие вопросы управления службами Windows:
- Получаем статус службы на локальном компьютере
- Получаем статус службы на удаленном компьютере
- Осуществляем фильтрацию служб (например, остановленные службы)
- Зависимые службы
Обозначим начальные условия: Вы работаете под Windows 7 и выше и у Вас имеются права администратора. Все команды рекомендуются выполнять в лабораторной или виртуальной среде, перед тем, как применять в “полевых условиях”.
ПОЛУЧАЕМ СТАТУС СЛУЖБЫ
Давайте начнем с того, что просто получим статус всех служб, запущенных на локальном компьютере. Используем для этого командлет Get-Service.
PS C:> get-service
PowerShell, как правило, не чувствителен к регистру. Вывод приведен на скриншоте ниже.
Каждая строка представляет собой объект службы (service object).Каждый сервисный объект, как правило, имеет свои свойства. Вы можете открыть их, просто передав эти объекты в другую команду, Get-Member.
PS C:> get-service | get-member
Результаты приведены на скриншоте ниже.
Параметр 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
Вы можете получить полную справочную информацию, напечатав:
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 отображает те объекты, которые остались в конвейере.
Результаты приведены ниже.
Теперь давайте попробуем найти одну службу на нескольких машинах. Вывод отформатируем в таблицу.
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
Написанное выше проще понять, если взглянуть на скриншот.
Что касается меня, то я бы предпочел использовать хеш-таблицу.
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
Результаты видны на скриншоте ниже.
Чтобы получить подобные результаты в 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. Программа отслеживает все автоматически запускаемые службы на группе серверов и в случае внезапного сбоя одной или нескольких из них отправляет уведомления по электронной почте. Функция перезапуска гарантирует, что все подконтрольные службы будут работать без простоев. Программа проста в настройке: устанавливаем, вводим имена компьютеров и указываем нужный адрес электронной почты.
Автор: NetWrixRU