Управляем службами Windows с помощью PoweShell. Часть 4. Изменение служб с помощью WMI

от автора


Продолжаем публиковать переводы статей по управлению службами Windows, которые выходят на сайте 4sysops.com. В предыдущем посте было рассмотрено использование WMI для извлечения информации о службе. WMI объект службы предлагает новые свойства, которые отсутствуют в .NET объекте службы. И хотя мы можем использовать Set-Service для изменения объекта службы, есть такие ситуации, когда вам необходимо использовать WMI.
Под катом приведен перевод статьи с портала 4sysops.com Managing Services the PowerShell way – Part 6.

Запуск и остановка

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

PS C:\> get-wmiobject win32_service -filter "name='lanmanserver'" | get-member -MemberType Method | Select name Name —- Change ChangeStartMode Delete GetSecurityDescriptor InterrogateService PauseService ResumeService SetSecurityDescriptor StartService StopService UserControlService 

Мы можем также получить ссылку на определенный объект службы и затем непосредственно вызвать метод (directly invoke a method).

PS C:\> $service = get-wmiobject win32_service -filter "name='spooler'" PS C:\> $service.state Running PS C:\> $service.StopService()  __GENUS          : 2 __CLASS          : __PARAMETERS __SUPERCLASS     : __DYNASTY        : __PARAMETERS __RELPATH        : __PROPERTY_COUNT : 1 __DERIVATION     : {} __SERVER         : __NAMESPACE      : __PATH           : ReturnValue      : 0 

Я прямо вызываю метод StopService() для объекта службы Spooler. Возвращенное значение (“0”) означает успех. Любое другое значение означает ошибку, посмотрите документацию на MSDN, посвященную классу Win32_Service.
Недостатком этого метода является то, что у него отсутствует параметр –Whatif. Поэтому я рекомендую использовать командлет Invoke-WmiMethod. Мы получаем WMI объект и передаем его в Invoke-WmiMethod.

PS C:\> get-wmiobject win32_service -filter "name='spooler'" | Invoke-WmiMethod  -Name StartService -WhatIf What if: Performing operation "Invoke-WmiMethod" on Target "Win32_Service  (StartService)". PS C:\> get-wmiobject win32_service -filter "name='spooler'" | Invoke-WmiMethod  -Name StartService  __GENUS          : 2 __CLASS          : __PARAMETERS __SUPERCLASS     : __DYNASTY        : __PARAMETERS __RELPATH        : __PROPERTY_COUNT : 1 __DERIVATION     : {} __SERVER         : __NAMESPACE      : __PATH           : ReturnValue      : 0 

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

PS C:\> get-wmiobject win32_service -filter "startmode='auto' AND state<>'Running'" -comp chi-dc03 | invoke-wmimethod -Name StartService 

Недостатком этого является то, что объект результата только показывает возвращенное значение. Если здесь отсутствуют множественные службы, я не могу узнать, какой результат у определенной службы. Чтобы решить эту проблему, используем вот такой вариант:

PS C:\> get-wmiobject win32_service -filter "startmode='auto' AND state<>'Running'"  -comp chi-dc01,chi-dc02,chi-dc03 | foreach { $svc = $_ ; $_ | Invoke-WmiMethod -Name  StartService | Select @{Name="Name";Expression={$svc.name}},@{Name="DisplayName"; Expression={$svc.Displayname}},ReturnValue,@{Name="Computername";Expression={ $svc.Systemname}}}  Name                     DisplayName                       ReturnValue Computername ----                     -----------                       ----------- ------------ sppsvc                   Software Protection                          0 CHI-DC01 sppsvc                   Software Protection                          0 CHI-DC02 VMTools                  VMware Tools Service                         7 CHI-DC02 ShellHWDetection         Shell Hardware Detection                     0 CHI-DC03 

К блоке ForEach я сохранил входной объект как переменную ($svc), так что я могу снова использовать ее в качестве части хеш-таблицы, определяющей кастомные свойства. Как вы можете видеть имеется одна ошибка для той службы, которую, как я думал, я удалил.

Меняем режим запуска

Вы также можете менять режим запуска службы. Опции таковы: Automatic, Disabled или Manual. С помощью WMI невозможно установить значения запуска службы Automatic (Delayed).

PS C:\> get-wmiobject win32_service -filter "name='spooler'" | Invoke-WmiMethod -Name  ChangeStartMode -ArgumentList "Manual" | Select ReturnValue  ReturnValue -----------           0 

Параметр ArgumentList показывает какое значение следует использовать. Запуск команды осуществляется с правами администратора.

Устанавливаем свойства службы

У объекта службы не так много свойств, которые вы можете менять. Некоторые WMI объекты могут быть изменены с помощью Set-WmiInstance. Но в случае с объектами служб, для объекта вам необходимо использовать метод Change(). Единственная проблема заключается в том, что у этого метода много параметров.

Change(
string DisplayName,
string PathName,
uint32 ServiceType,
uint32 ErrorControl,
string StartMode,
boolean DesktopInteract,
string StartName,
string StartPassword,
string LoadOrderGroup,
string LoadOrderGroupDependencies,
string ServiceDependencies
)

Вы должны включить эти параметры в метод до того, который вы хотите использовать последним. Используйте значение $Null для тех параметров, которые вы хотите пропустить. Например: скажем, я хочу изменить свойство ErrorControl службы Spooler с Normal на Ignore. Исследовав свойство класса, я обнаруживаю, что Normal соответствует значение 1, а Ignore 0. Теперь давайте поработаем с PowerShell.

PS C:\> Get-WmiObject win32_service -filter "Name='Spooler'" | Invoke-WmiMethod  -Name Change -ArgumentList @($null,$null,$null,0) | Select ReturnValue  ReturnValue -----------           0 

Выглядит так, будто все работает, проверим.

PS C:\> get-wmiobject win32_service -filter "Name='spooler'" | select  name,errorcontrol  name                                                        errorcontrol     ----                                                        ------------     Spooler                                                     Normal 

Ан нет! Так вышло, что у PowerShell есть небольшая “причуда”, о которой вы должны знать. Даже хотя WMI метод ожидает параметров в заданном порядке, ErrorControl должен быть на четвертом месте, когда используете Invoke-WmiMethod, порядок по алфавиту. И не спрашивайте почему. Вот что я делаю, чтобы определить “правильный” порядок.

PS C:\> $svc = Get-WmiObject win32_service -filter "name='spooler'"  __GENUS                    : 2 __CLASS                    : __PARAMETERS __SUPERCLASS               :  __DYNASTY                  : __PARAMETERS __RELPATH                  :  __PROPERTY_COUNT           : 11 __DERIVATION               : {} __SERVER                   :  __NAMESPACE                :  __PATH                     :  DesktopInteract            :  DisplayName                :  ErrorControl               :  LoadOrderGroup             :  LoadOrderGroupDependencies :  PathName                   :  ServiceDependencies        :  ServiceType                :  StartMode                  :  StartName                  :  StartPassword              :  PSComputerName             : 

В этом списке ErrorControl находится на 3 месте, так что я могу заново запустить изменённое выражение Invoke-WmiMethod.

PS C:\> Get-WmiObject win32_service -filter "Name='Spooler'" | Invoke-WmiMethod -Name Change -ArgumentList @($null,$null,0) 

Проверим еще раз и получим желаемый результат.

PS C:\> get-wmiobject win32_service -filter "Name='spooler'" | select  name,errorcontrol  name                                                        errorcontrol     ----                                                        ------------     Spooler                                                     Ignore 

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

Итог

Использование WMI для управления службами в вашей среде довольно полезно, особенно для тех ситуаций, когда единственный вариант – WMI. Но если вы работаете с PowerShell 3.0, вы также можете использовать CIM командлеты, которые я рассмотрю в следующей статье.

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


Комментарии

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

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