Продолжаем публиковать переводы статей по управлению службами Windows, которые выходят на сайте 4sysops.com. В предыдущем посте было рассмотрено как осуществлять управление службами Windows, используя WMI. Но если вы работаете с PowerShell 3.0, то вам доступны новые CIM-командлеты. Работать с ними проще — и в этом посте мы узнаем почему.
Итак, под катом приведен перевод статьи с портала 4sysops.com Managing Services the PowerShell way – Part 7
Остановка и запуск служб с помощью CIM командлетов
Одним из важных отличий CIM-объекта от “чистого” WMI является то, что результирующий объект (resultant object) не имеет методов. А это значит, что вы не можете непосредственно извлекать (invoke) метод, например, StopService(). Вместо этого используйте командлет Invoke-CimMethod. Рассмотрим пример для службы spooler на локальном компьютере.
PS C:> get-ciminstance win32_service -filter "Name='spooler'"
ProcessId Name StartMode State Status ExitCode
--------- ---- --------- ----- ------ --------
0 Spooler Manual Stopped OK 1077
Как в случае с WMI, проще всего передать объект в командлет Invoke-CimMethod.
PS C:> get-ciminstance win32_service -filter "Name='spooler'" | Invoke-CimMethod
-Name StartService
ReturnValue PSComputerName
----------- --------------
0
Работа этого командлета во много схода с Invoke-WmiMethod. Возвращенное значение, равное 0, обозначает успех. Давайте теперь рассмотрим предыдущий запрос, в котором требовалось найти все службы с автостартом, но которые не были запущены.
PS C:> get-ciminstance win32_service -filter "startmode='auto' and state<>'running'" -computer $computers | Invoke-CimMethod -Name StartService –WhatIf
Переменная $computers включает в себя список всех интересующих нас компьютеров. Используйте -Whatif.
Чтобы внести изменения, запустим команду, но уже без –WhatIf.
PS C:> get-ciminstance win32_service -filter "startmode='auto' and state<>'running'" -computer $computers | Invoke-CimMethod -Name StartService
На скриншоте можно видеть, что проблема имеется у компьютера chi-dc02 (ReturnValue отличается от 0).
Давайте поработаем с тем, что я делал в предыдущей статье, используя Invoke-WmiMethod. Сейчас я работаю в PowerShell 3.0, так что можно взять каждый объект службы, запустить его и создать кастомный объект для выведения результатов.
get-ciminstance win32_service -filter "startmode='auto' and state<>'running'"
-computer $computers |
foreach {
$result = $_ | Invoke-CimMethod -Name StartService
#create a custom object
[pscustomobject]@{
Result=$Result.ReturnValue
Name=$_.Name
DisplayName=$_.Displayname
Computername=$Result.PSComputername
}
} | Sort Computername,Name
Стало проще, не так ли?
Можно добавить и другие кастомные свойства, например дату и время. Чтобы вывести только ошибки, слегка изменим правила сортировки.
... | Sort Computername,Name | Where {$_.result -gt 0}
Result Name DisplayName Computername
------ ---- ----------- ------------
7 VMTools VMware Tools Service chi-dc02
2 gpsvc Group Policy Client chi-win8-01
Меняем режим запуска (StartMode)
Поменять свойство службы (например, Startmode) также просто. Например, мне не нужно, чтобы служба Remote Access Connection Manager была запущена в сети. Так что я собираюсь отключить ее везде.
PS C:> get-ciminstance win32_service -filter "name='rasman'" -comp $computers |
Invoke-CimMethod -methodname ChangeStartmode -Arguments @{startmode='Disabled'}
ReturnValue PSComputerName
----------- --------------
0 chi-win8-01
0 chi-dc03
0 chi-db01
0 chi-ex01
Небольшое отличие от Invoke-WmiMethod – список аргументов должен быть в виде объекта словаря (dictionary object). Сложность здесь заключается в определении ключа, которым в данном случае является StartMode. Лучше обратиться к документации для метода WMI и посмотреть имя параметра. Внимательный читатель обратил внимание на то, что я использовал –MethodName вместо привычного (и использовавшегося ранее) параметра –Name. –Name – это недокументированное сокращение для параметра –MethodName.
Так как мы используется объект словаря (dictionary object) для параметров метода, проще извлечь Change метод для объекта службы. В предыдущей статье для службы Spooler мы установили значение свойства ErrorControl равным Ignore. Давайте вернем его значение в Normal, используя теперь CIM командлеты.
PS C:> get-ciminstance win32_service -filter "name='spooler'" | Invoke-CimMethod
-MethodName Change -Arguments @{ErrorControl=1}
ReturnValue PSComputerName
----------- --------------
0
Это гораздо проще. Не нужно вычислять позиции и добавлять пустые ($Null) значения. Выберите метод параметра и с делом покончено.
Итог
Почему стоит использовать CIM командлеты: более простое удаленное управление и “дружеские отношения” с файрволом. Конечно, требуется PowerShell 3.0. Все, что вы можете сделать для управления службами с помощью WMI, можно сделать и с помощью CIM командлетов, зачастую требуется меньших усилий для этого.
Я также наткнулся на одну особенность CIM командлетов. В нормальных условиях удаленный компьютер должен также работать c PowerShell 3.0. Это справедливо, когда вы передаете все экземпляры заданного класса. Но когда вы используете фильтр, как я часто делаю в этой статье, то я могу делать запрос с использованием Get-CimInstance даже если на удаленном компьютере работает PowerShell 2.0! Я до сих пор выясняю, почему так. В любом случае, напоминаю, что нужно тестировать все, что мы рассматриваем в лабораторной среде.
В следующей статье мы посмотрим на управление учетными данными (credentials), под которыми запущена служба.
Автор: AMarkin