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

в 8:22, , рубрики: powershell, Блог компании NetWrix, системное администрирование

Управляем службами 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 командлеты, которые я рассмотрю в следующей статье.

Автор: AMarkin

Источник

Поделиться

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