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

в 12:19, , рубрики: powershell, service management, Блог компании NetWrix, системное администрирование, управление службами

Управляем службами 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. Программа отслеживает все автоматически запускаемые службы на группе серверов и в случае внезапного сбоя одной или нескольких из них отправляет уведомления по электронной почте. Функция перезапуска гарантирует, что все подконтрольные службы будут работать без простоев. Программа проста в настройке: устанавливаем, вводим имена компьютеров и указываем нужный адрес электронной почты.

Автор: NetWrixRU

Источник

Поделиться

* - обязательные к заполнению поля