Powershell не удалось открыть службу на компьютере
03.06.2020
itpro
PowerShell
комментария 4
Из любого скрипта PowerShell можно сделать службу Windows, которая работает в фоновом режиме и запускается автоматически при загрузке сервера. Вы можете создать службу Windows с помощью утилит srvany.exe и instsrv.exe (из состава Windows Server Resource 2003 Kit), позволяющих запустить процесс powershell.exe с параметром в виде пути к ps1 файлу скрипта. Основной недостаток такого способа создания службы — srvany.exe не контролирует выполнение приложения (скрипта PowerShell в нашем случае) и, если приложение падает (зависает), то служба это не видит и продолжает работать. В этой статье для создания службы Windows из файла со скриптом PowerShell мы будем использовать утилиту NSSM (Non-Sucking Service Manager – оставим без перевода…:)), которая лишена этих недостатков.
Вы можете скачать и установить NSSM вручную или через Chocolately. Сначала нужно разрешить запуск PS1 скриптов в сесиии и установить сам Choco:
Затем установим пакет NSSM:
choco install nssm
В этом примере мы будем в реальном времени отслеживать изменения определенной группы AD (скрипт из этой статьи) и при изменении оповещать администратора безопасности всплывающим уведомлением и письмом.
Итак, у нас имеется код, который нужно сохранить в PS1 файл. Добавим бесконечный цикл, который раз в минуту выполняет проверку:
Конечно, для реализации подобного сценария можно создать и задание в планировщике (Task Scheduler), но если вам нужно реагировать на любые изменения в реальном времени, метод с отдельной службой гораздо правильнее.
Создать службу из скрипта PowerShell при помощи NSSM можно прямо из PowerShell :):
$NSSMPath = (Get-Command "C:\tools\nssm\win64\nssm.exe").Source
$NewServiceName = “CheckADGroupSrv”
$PoShPath= (Get-Command powershell).Source
$PoShScriptPath = “C:\tools\CheckADGroup\checkad.ps1”
$args = '-ExecutionPolicy Bypass -NoProfile -File ""' -f $PoShScriptPath
& $NSSMPath install $NewServiceName $PoShPath $args
& $NSSMPath status $NewServiceName
Запустим новую службу:
Итак, вы создали и запустили новую службу Windows. Проверим, что она появилась в консоли управления службами services.msc
Служба CheckADGroupSrv действительно появилась, она настроена на автоматический запус и в данный момент запущена (Running). Как вы видите, ваш PowerShell скрипт запущен внутри процесса nssm.exe.
Обратите внимание, что служба запущена из-под учетной записи System. Если вы используете в своих PS скриптах другие модули (в моем случае для получения состава доменной группы безопасности используется командлет Get-ADGroupMember из модуля Active Directory для Windows PowerShell), этот аккаунт должен иметь доступ к файлам модуля и права на подключение к AD (в моем случае). Вы так же можете запустить эту службы под другой учётной записью (или аккаунтом gMSA) и предоставить пользователям права на остановку/перезапуск службы, если у них нет прав локального администратора.
Чтобы это работало в Windows 10 / Windows Server 2012 R2/ 2016 нужно изменить значение DWORD параметра реестра NoInteractiveServices в ветке HKLM\System\CurrentControlSet\Control\Windows на 0 и включить службу обозревателя интерактивных служб (Interactive Services Detection Service):
Start-Service -Name ui0detect
Однако в Windows 10 1803 службу Interactive Services Detection Service полностью убрали из системы, и вы более не можете переключиться в нулевую сессию (Session 0), так что вы просто не увидите окна, которые выводятся из-под аккаунта System.
Вы можете изменить описание службы командой:
& $NSSMPath set $NewServiceName description “Мониторинг изменений группы AD”
Чтобы удалить созданную службу можете воспользоваться командой sc delete или
05.08.2021
itpro
Windows 10, Windows Server 2016, Windows Server 2019
комментариев 5
Как завершить процесс службы Windows, которая зависла в статусе stopping (остановка) или starting (запуск)? Большинство администраторов Windows встречалось с ситуациями, когда при попытке остановить (перезапустить) службу из графического интерфейса консоли управления службами ( Services.msc ), служба зависает намертво и висит в статусе Stopping (или Starting). При этом все кнопки управления службой в консоли (Start, Stop, Restart) становятся недоступными (серыми). Самый простой способ – перезагрузить сервер, но это не всегда допустимо. Рассмотрим альтернативные способы, позволяющие принудительно завершить зависшую службу или процесс без необходимости перезагрузки Windows.
Создание и удаление служб Windows c помощью PowerShell
New-Service – командлет для создания новой службы в Windows. Для новой службы требуется указать имя и исполняемый файл (вы можете запустить PowerShell скрипт как службу Windows).
В примере создадим новую службу с именем TestService.
new-service -name TestService -binaryPathName "C:\WINDOWS\System32\svchost.exe -k netsvcs"
С помощью параметра Get-WmiObject получим информацию о режиме запуска и описание службы
get-wmiobject win32_service -filter "name='testservice'"
Изменить параметры новой службы можно командой
Set-Service -Name TestService -Description ‘My Service’ -StartupType Manual
Чтобы удалить службу используйте команду
(Get-WmiObject win32_service -Filter ″name=′TestService′″).delete()
Изменение учетной записи для запуска службы
Вы можете изменить учетную запись, из-под которой запускается служба. Получим имя учетной записи, которая используется для запуска службы TestService
get-wmiobject win32_service -filter "name='TestService'" | Select name,startname
Для изменения имени и пароля учетной записи выполняем команды.
$svc = get-wmiobject win32_service -filter "name='TestService'"
$svc.GetMethodParameters("change")
В результате получаем список параметров метода Change(). Считаем на каком месте находятся параметры StartName и StartPassword – 20 и 21 место соответственно.
$svc | Invoke-WmiMethod -Name Change –ArgumentList @ ($null,$null,$null,$null,$null,$null,$null, $null,$null,$null,$null,$null,$null,$null,$null,$null, $null,$null,$null,"Administrator","P@ssw0rd")
Либо вы можете указать имя gMSA аккаунта. Пароль при этом не указывается.
Как видите, PowerShell позволяет легко управлять службами Windows. Можно создавать, останавливать, запускать и возобновлять службы, менять их свойства. Большинство командлетов позволяют управлять службами на удаленных компьютерах.
Так как команда для получения статуса службы называется Get-Service, догадаться о том, как пишутся другие команды не составит труда. На худой конец мы можем спросить у PowerShell обо всех командах, так или иначе относящихся к работе со службами. Обратите внимание, что мы использовали параметр –noun для получения всех команд, связанных со службами.
Взглянем на эти команды внимательнее.
STOP-SERVICE
Чтобы остановить службу, мы должны уточнить ее имя.
Однако в конвейер ничего не будет передано. Некоторые командлеты, такие как Stop-Service, созданы таким образом, что по умолчанию они не записывают объект в конвейер. Мы же заставим это сделать, использовав параметр –Passthru.
Если служба не запущена, то командлет ничего не выведет, равно как и не выдаст никакой ошибки. Поэтому иногда лучше передать объект в Stop-Service (естественно использовав при этом параметр –whatif).
Параметр –WhatIf был добавлен для того, чтобы мы посмотрели, что будет, если командлет будет запущен. Когда я удостоверюсь, что это именно та служба, которая меня интересует, я просто удалю -Whatif и остановлю службу.
Как я уже упомянул выше, если служба уже остановлена, то командлет ничего не сделает. И использование Stop-Service в этом случае никому не навредит. Однако я все же предпочитают более цивилизованный подход, а именно:
Если служба запущена, то объект передается в конвейер и отправляется в Stop-Service. Ниже приведен вариант с остановкой нескольких служб.
Некоторые службы не захотят останавливаться – в силу наличия зависимых служб – что мы и видим на скриншоте ниже.
В таком случае используем параметр –Force. В большинстве случаев это работает, но без “защиты от дурака”. Помните, что команда также остановит зависимые службы.
START-SERVICE
Запуск службы осуществляется аналогичным образом. Он поддерживает параметр –Whatif, и вам придется использовать –Passthru, чтобы увидеть объекты.
И снова: если служба уже запущена, командлет ничего не сделает. Однако вы можете попытаться запустить службу и получите такую ошибку.
Причиной тому в большинстве случаев является выключенные службы. Как конфигурировать настройки службы, я расскажу в следующей статье.
Если вы хотите запустить службы и все службы, зависимые от нее, используйте следующее выражение:
Мы должны явно получить зависимые службы, потому что Start-Service не запустит автоматически их.
RESTART-SERVICE
Вы удивитесь, но перезапуск службы работает также как два предыдущих примера. Используйте –Passthru, если хотите убедиться, что служба запущена.
Так как мы осуществляем остановку службы, нам может понадобиться параметр –Force.
ПРИОСТАНОВКА И ВОЗОБНОВЛЕНИЕ РАБОТЫ
Работа некоторых служб может быть приостановлена на некоторое время, а затем возобновлена, и мы можем это сделать через PowerShell. Однако если служба не удовлетворяет требованиям, мы получим такие ошибки. (на примере показано, что мы пытались приостановить службу bits)
В чем же проблема? Смотрим на объект (используя Get-Service).
Если значение свойства CanPauseAndContinue равно True, значит мы можем приостанавливать и возобновлять работу службы. Найдем такие службы:
Как мы видим, не так много служб удовлетворяют этому требованию.
Готовы возобновить работу службы? Используйте следующее выражение:
Оба командлета также поддерживают –Whatif.
УДАЛЕННЫЕ СЛУЖБЫ
Как вы могли обратить внимание, все примере выше мы демонстрировали на локальном машине. И это неслучайно. К сожалению даже в PowerShell v3, ни у одного из этих командлетов нет параметра, который позволял бы управлять службой на удаленном компьютере. Get-Service, конечно, поддерживает параметр –Computername, но не более. Службу лицезреть вы сможете, а что-либо с ней сделать не получится. Нет, можно, конечно, если удаленный компьютер работает с PS v2 и включен PowerShell Remoting. Тогда мы можете использовать все выше приведенные команды, используя Invoke-Command для удаленного компьютера или PSSession. С другой стороны, проще управлять одной службой на нескольких серверах.
Управление службами на удаленных компьютерах не ограничивается вышеперечисленным, но это уже будет предмет рассмотрения последующих статей.
Все эти командлеты могут быть использованы в конвейерном выражении и зачастую это лучший вариант. Использование Get-Service для получения объектов и последующая передача их в подходящий командлет.
УСТАНАВЛИВАЕМ УДАЛЕННЫЙ СТАТУС
Итак, мы выяснили, что у командлета Stop-Service отсутствует такой полезный параметр как –Computername. Мы можете использовать эти команды в удаленной сессии, обратившись к командлету Invoke-Command, что уже само по себе продуктивно, если вы работаете со службой на нескольких компьютерах. Одно можно запускать, останавливать, перезапускать, ставить на паузу и запускать заново, используя Set-Service.
Эта команда поддерживает параметр –WhatIf. Вы также должны использовать –Passthru для передачи объектов в конвейер.
Валидными значениям для параметра –Status являются “запущена” (running), “остановлена” (stopped) и “на паузе” (paused). Помните, что у службы есть зависимые службы, мы не сможете изменять ее, что и продемонстрировано на скриншоте ниже.
К сожалению, у Set-Service отсутствует параметр –Force, поэтому придется вернуться к использованию PowerShell remoting и Invoke-Command. Если вы хотите перезапустить удаленную службу, используйте следующую команду:
Не забудьте использовать –Passthru, в противном случае вторая команда Set-Service ничего не осуществит.
Что по мне, так я предпочитаю работать сразу с несколькими службами, которые я не могу удаленно остановить, используя Set-Service, хотя их запуск проблем составляет. Я использую Invoke-Command. Но помните, что используя параметр –Computername PowerShell осуществляет подключение, используя RPC и DCOM, что может привести к проблемам с файрволом. Invoke-Command использует PowerShell remoting, который мы может быть еще не настроили или не включили.
УСТАНАВЛИВАЕМ ТИП АВТОЗАПУСКА СЛУЖБЫ
Set-Service полезнен, когда вы хотите включить или отключить службу, используя параметр –StartupType. Если Вы настроили службу, используя значения Automatic, Manual or Disabled. К сожалению, не существует варианта для Automatic (Delayed).
Однако, просто взглянув на объект, мы не сможем сказать, к какому типу автозагрузки он относится.
Как это сделать – одна из тем следующей статьи.
Помните, что изменение типа автозагрузки не повлияет на текущий статус службы.
Так что если вы хотите выключить и остановить (или включить и запустить) службу, передайте объект в подходящий командлет.
Технически, Set-Service позволяет вам изменить отображаемое имя службы и описание, но лично мне никогда не приходилось использовать в своей работе. Я использую Set-Service для включения и выключения служб. Если необходимо управлять службами удаленно, то я использую Invoke-Command.
Все, что я продемонстрировал в последних статьях, было связано с использованием специфических типов объектов службы, которые, как вы могли заметить, имеют некоторые ограничения. В следующей статье мы рассмотрим другие возможности по управлению службами, которые призваны обойти эти ограничения.
Давайте начнем с того, что просто получим статус всех служб, запущенных на локальном компьютере. Используем для этого командлет Get-Service.
PowerShell, как правило, не чувствителен к регистру. Вывод приведен на скриншоте ниже.
Каждая строка представляет собой объект службы (service object).Каждый сервисный объект, как правило, имеет свои свойства. Вы можете открыть их, просто передав эти объекты в другую команду, Get-Member.
Результаты приведены на скриншоте ниже.
Параметр Typename сверху говорит о том, что за объект перед нами; в данном случае это System.ServiceProcess.ServiceController. На скриншоте также обведены свойства объекта. Это атрибуты, которые описывают этот тип объекта. Хотя большинство из них не используются при отображении по умолчанию, вы можете использовать их, если вы их знаете.
Например, нам интересно посмотреть информацию только о Windows Update. Через Get-Service получим информацию только о некоторых ее свойствах.
Как я узнал, что могу напечатать имя службы? Посмотрел с помощью Get-Service.
PS C:\> help get-service
Вы можете получить полную справочную информацию, напечатав:
Информацию о службе можно получить по ее имени или даже начальным буквам имени.
Или если вам удобнее работать с отображаемыми именами, используйте параметр –Displayname.
Я должен использовать имя параметра, чтобы PowerShell воспринимал значения в качестве отображаемого имени, а не фактического имени службы. Команда будет выглядеть так:
Параметр –Name можно не печатать.
ПОЛУЧАЕМ СТАТУС СЛУЖБЫ НА УДАЛЕННЫХ КОМПЬЮТЕРАХ
До этого нас интересовало получение информации о статусе служб на локальном компьютере. Однако управление службами осуществляется на удаленных компьютерах. Если посмотреть справку по Get-Service, то можно увидеть наличие у этого командлета параметра –Computername. В данном случае подключение к удаленным компьютерам осуществляется без включения функции удаленного управления PowerShell. Если вы можете управлять службами, используя инструменты командной строки (sc.exe или консоль управления Service Manager), вы можете использовать PowerShell. Давайте взглянем на пример:
Любая команда, которую я демонстрировал, можно использовать для передачи удаленному компьютеру. Даже нескольким компьютерам, если у вас есть соответствующие права на удаленном компьютере. Если вы используете PowerShell v3, то можно легко выбрать одну службу на множестве компьютеров.
Для наглядности представления отформатируем вывод.
Тот же самый результат, но в PowerShell v2.
ОСУЩЕСТВЛЯЕМ ФИЛЬТРАЦИЮ (ИСПОЛЬЗУЯ WHERE-OBJECT)
Фильтрация служб осуществляется с помощью командлета Where-Object (where – сокращение для командлета). Все, что нам нужно от PowerShell в этом случае, так это получить только те службы, у которых статус равен “stopped”.
PowerShell получает информацию обо всех службах и передает их (с помощью “|”) в следующую команду, которая осуществляет просмотр каждого объекта. Если свойство статуса объекта равно “stopped”, она остается в конвейере (pipeline), в противном случае она из него исключается. В конце выражение PowerShell отображает те объекты, которые остались в конвейере.
Результаты приведены ниже.
Теперь давайте попробуем найти одну службу на нескольких машинах. Вывод отформатируем в таблицу.
Мы даже можем комбинировать запрос отдельных служб с их фильтрацией.
Эта команда находит все службы на компьютере CHI-DC03, которые начинаются с ‘WIN’, но отображает только те, которые запущены.
Также можно сгруппировать объекты по свойству статуса (status property).
Переменная $dc03 является объектом GroupInfo.
Свойство Group представляет собой коллекцию связанных служб.
Написанное выше проще понять, если взглянуть на скриншот.
Что касается меня, то я бы предпочел использовать хеш-таблицу.
Теперь каждое имя представляет собой свойство в хеш-таблице. Если у вас имеется опыт работы с PoweShell, вы, возможно, подумываете сделать сделующее:
В чем суть параметра –AsString, на мой взгляд, достаточно очевидно. Теперь работать с хеш-таблицей стало проще.
Следующей задачей на повестке дня является проверка зависимостей сервера (server dependencies).
Требуемые службы
PowerShell позволяет просто получить статус всех служб, которые требуется для данной службы, даже на удаленном компьютере.
Параметр –RequiredServices передаст объект в конвейер для каждой требуемой службы. Вы можете даже пойти дальше и проверить требуемые службы для работы данной службы.
Параметр –Computername командлета Get-Service возьмет вывод, но только для тех объектов, у которых есть объект свойство Computername – именно поэтому я использую хеш-таблицу с Select-Object. Как мы видим проблем со службой DNS на компьютере CHI-DC03 нет.
ЗАВИСИМЫЕ СЛУЖБЫ
Мы можем сделать то же самое с зависимыми службами. Если таковых не имеется, в конвейер ничего передано не будет.
Требуемые и зависимые службы также являются частью каждого объекта службы.
А пока Вы можете получить все зависимости для всех служб, следующая команда
Это не даст вам особо полезную информацию, поэтому я рекомендую осуществлять запрос по конкретным службам. Команда работает гораздо лучше PowerShell v3.
Результаты видны на скриншоте ниже.
Чтобы получить подобные результаты в PowerShell v2, вам придется передать имена компьютеров (computernames) в Get-Service.
В следующей статье будет рассмотрен запуск, остановка и перезапуск служб.
Конец перевода.
P.S. Хотим также поделиться нашей бесплатной программой для управления службами Windows – NetWrix Service Monitor. Программа отслеживает все автоматически запускаемые службы на группе серверов и в случае внезапного сбоя одной или нескольких из них отправляет уведомления по электронной почте. Функция перезапуска гарантирует, что все подконтрольные службы будут работать без простоев. Программа проста в настройке: устанавливаем, вводим имена компьютеров и указываем нужный адрес электронной почты.
Основные командлеты PowerShell для управления службами Windows
Существует восемь основных командлетов Service, предназначенных для просмотра состояния и управления службами Windows.
Чтобы получить весь список командлетов Service, введите команду:
Получить подробное описание и примеры использования конкретного командлета можно через Get-help:
Get-Service: получаем список служб и их состояние
Получить список и состояние (Running/Stopped) службы на локальном или удаленном компьютере можно с помощью командлета Get-Service. Параметр -Name позволяет делать отбор по имени службы. Имя службы можно задать с использованием подстановочного символа *.
Если вы не знаете точное имя службы, есть возможность найти службы по отображаемому имени с помощью параметра –DisplayName. Можно использовать список значений и подстановочные знаки.
.
Командлет Get-Service можно использовать для получения состояния служб на удаленных компьютерах, указав параметр -ComputerName. Можно опросить статус службы сразу на множестве удаленных компьютеров, их имена нужно перечислить через запятую. Например, приведенная ниже команда получает состояние службы Spooler на удаленных компьютерах RM1 и RM2.
Get-Service spooler –ComputerName RM1,RM2
Вывести все свойства службы позволит командлет Select-Object:
Get-Service spooler | Select-Object *
Командлет Select-Object позволит вывести определенные свойства службы. Например, нам нужно вывести имя, статус и доступные возможности службы Spooler:
Get-Service Spooler | Select DisplayName,Status,ServiceName,Can*
Командлет Get-Service имеет два параметра, которые позволяют получить зависимости служб:
- Параметр -DependentServices позволяет вывести службы, которые зависят от данной службы;
- Параметр -RequiredServices позволяет вывести службы, от которых зависит данная служба.
Приведенная ниже команда выводит службы, необходимые для запуска службе Spooler:
Get-Service –Name Spooler -RequiredServices
Следующая команда выводит службы, которые зависят от службы Spooler:
Get-Service –Name Spooler -DependentServices
При необходимости найти службы с определенным состоянием или параметрами, используйте командлет Where-Object. Например, получим список запущенных служб со статусом Running:
Для вывода служб с типом запуска Manual, выполните команду
.starttype -eq " width="" />
.starttype -eq " width="" />
Проверить, что в системе имеется указанная служба:
if (Get-Service "ServiceTest" -ErrorAction SilentlyContinue)
Как остановить зависшую службу Windows из командной строки?
Самый простой способ завершить зависшую служу – воспользоваться утилитой taskkill. В первую очередь нужно определить PID (идентификатор процесса) нашей службы. В качестве примера возьмем службу Windows Update. Ее системное имя wuauserv (имя можно посмотреть в свойствах службы в консоли services.msc ).
Очень часто можно встретится с зависанием службы Windows Modules Installer при перезагрузке сервера, особенно после установки обновлений на Windows Server 2012 R2 / 2016.
Важно. Будьте внимательными. Принудительная отставка процесса критичной службы Windows может привести к BSOD или перезагрузке операционной системы.
Отройте командную строку с правами правами администратора (иначе будет ошибка access denied) и выполите команду:
sc queryex wuauserv
В данном случае PID процесса — 9186 .
Чтобы принудительно завершить зависший процесс с PID 9186 воспользуйтесь утилитой taskkill:
taskkill /PID 9168 /F
Данная команда принудительно завершит процесс службы. Теперь вы можете запустите службу командой sc start servicename или через консоль управления службами (или совсем удалить эту службу, если она не нужна).
«Выстрел в голову» зависшей службы можно выполнить и более элегантно, не выполняя ручное определение PID процесса. У утилиты taskkill есть параметр /FI, позволяющий использовать фильтр для выбора необходимых служб или процессов. Вы можете остановить конкретную службу командой:
TASKKILL /F /FI “SERVICES eq wuauserv”
Или можно вообще не указывать имя, службы, завершив все сервисы в зависшем состоянии с помощью команды:
taskkill /F /FI “status eq not responding”
После этого служба, зависшая в статусе Stopping должна остановиться.
Также вы можете использовать утилиту taskkill для принудительной остановки зависших служб на удаленном компьютере:
TASKKILL /S CORPFS01 /F /FI “SERVICES eq wuauserv”
Set-Service – изменение настроек службы Windows
Командлет Set-Service позволяет изменить параметры или настройки служб на локальном или удаленном компьютере. Так как состояние службы является свойством, этот командлет можно использовать для запуска, остановки и приостановки службы. Командлет Set-Service имеет параметр -StartupType, позволяющий изменять тип запуска службы.
Изменим тип запуска службы spooler на автоматический:
Set-Service spooler –startuptype automatic –passthru
Можно перевести службу на ручной (manual) запуск:
Set-Service spooler –startuptype manual –passthru
Process Explorer: Завершение зависшего процесса из-под SYSTEM
Некоторые процессы, запущенные из-под SYSTEM, не может завершить даже локальный администратора сервера. Дело в том, что у него просто может не быть прав на некоторые процессы или службы. Чтобы завершить такие процесс (службы), вам необходимо предоставить локальной группе Administrators права на службу (процесс), а потом завершить их. Для этого нам понадобятся две утилиты: psexec.exe и ProcessExplorer (доступны на сайте Microsoft).
Обратите внимание, что права на службу и ее процесс выдались временно, до ее перезапуска. Для предоставления постоянных прав на службы познакомьтесь со статьей Права на службы в Windows.
Таймаут, в течении которого Service Control Manager ждет ожидания запуска или остановки службы можно изменить через параметр реестра ServicesPipeTimeout. Если служба не запускается в течении указанного таймаута, Windows записывает ошибку в Event Log (Event ID: 7000, 7009, 7011, A timeout was reached 30000 milliseconds). Вы можете увеличить этот таймаут, например до 60 секунд:
reg add HKLM\SYSTEM\CurrentControlSet\Control /v ServicesPipeTimeout /t REG_SZ /d 600000 /f
Это бывает полезным при запуске/остановки тяжелых служб, которые не успевают завершить все процессы быстро (например, MS SQL Server).
27.07.2020
itpro
PowerShell, Windows 10, Windows Server 2016
комментария 4
В Windows вы можете управлять службами не только из графической консоли services.msc или утилиты командной строки Sc.exe (первоначальна включалась в пакет ресурсов Resource Kit), но и с помощью PowerShell. В этой статье мы смотрим различные сценарии управления службами Windows с помощью PowerShell.
Анализ цепочки ожидания зависшего приложения с помощью ResMon
Вы можете определить процесс, из-за которого зависла служба с помощью монитора ресурсов ( resmon.exe ).
- В окне Монитора ресурсов перейдите на вкладку ЦП (CPU) и найдите процесс зависшей службы;
- Выберите пункт Анализ цепочки ожидания (Analyze Wait Chain);
- В новом окне скорее всего вы увидите, что вам процесс ожидает другой процесс. Завершите его. Если выполняется ожидание системного процесса svchost.exe, завершать его не нужно. Попробуйте проанализировать цепочку ожидания для этого процесса. Найдите PID процесса, которого ожидает ваш svchost.exe и завершите его
Остановка, запуск, приостановка и перезапуск служб из PowerShell
Остановить службу можно с помощью командлета Stop-Service. Чтобы остановить службу печати, выполните команду:
Stop-Service -Name spooler
Командлет Stop-Service не выводит никаких данных после выполнения. Чтобы увидеть результат выполнения команды, используйте параметр -PassThru.
Обратите внимание, что не каждую службу можно остановить. Если есть зависимые службы, то получите ошибку
Для принудительной остановки используйте параметр –Force. Вы должны помнить, что остановятся также все зависимые службы:
Stop-Service samss –Force -Passthru
Следующая команда остановит перечисленные службы (bits,spooler) со статусом ”Running”:
get-service bits,spooler | where | stop-service –passthru
Командлет Start-Service запускает остановленные службы:
Start-Service -Name spooler -PassThru
Служба не запустится, если есть остановленные зависимые службы. Чтобы их найти и включить:
get-service samss | Foreach
Командлет Suspend-Service может приостанавливать службы, допускающие временную приостановку и возобновление. Для получения сведений о возможности временной приостановки конкретной службы используйте командлет Get-Service со свойством «CanPauseAndContinue«.
Get-Service samss | Format-List name, canpauseandcontinue
Чтобы отобразить список всех служб, работа которых может быть приостановлена, введите команду:
Приостановим службу SQLBrowser:
Suspend-Service -Name SQLBrowser
Для возобновления работы приостановленной службы служит командлет Resume-service:
Resume-Service -Name SQLBrowser
Следующая команда возобновляет работу всех приостановленных служб:
get-service | where-object | resume-service
Командлет Restart-Service перезапускает службу:
Restart-Service -Name spooler
Эта команда запускает все остановленные сетевые службы компьютера:
get-service net* | where-object | restart-service
Параметр —ComputerName у этих командлетов отсутствует, но их можно выполнить на удаленном компьютере с помощью командлета Invoke-Command или через пайп:
Например, чтобы перезапустите очередь печати на удаленном компьютере RM1, выполните команду:
Get-Service Spooler -ComputerName RM1 | Start-Service
По умолчанию только администраторы могут запускать/останавливать службы в Windows, но вы можете предоставить права на перезапуск конкретной службы и обычным пользователям.
Принудительное завершение зависшей службы в PowerShell
Также вы можете использовать PowerShell для принудительной остановки службы. С помощью следующей команды можно получить список служб, находящихся в состоянии Stopping:
Get-WmiObject -Class win32_service | Where-Object
Завершить процесс для всех найденных служб поможет командлет Stop-Process. Следующий PowerShell скрипт завершит все процессы зависших служб в Windows:
$Services = Get-WmiObject -Class win32_service -Filter "state = 'stop pending'"
if ($Services) foreach ($service in $Services) try Stop-Process -Id $service.processid -Force -PassThru -ErrorAction Stop
>
catch Write-Warning -Message " Error. Error details: $_.Exception.Message"
>
>
>
else Write-Output "No services with 'Stopping'.status"
>
В новом PowerShell Core 6.x/7.x вместо командлета Get-WmiObject нужно использовать Get-CimInstance. Замените первую команду скрипта на:
$Services = Get-CimInstance -Class win32_service | where-Object state -eq 'stop pending'
Читайте также: