Продолжаем публиковать переводы статей по управлению службами 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/
Добавить комментарий