Проверка работы служб windows

Начинаем серию переводов, посвященную управлению службами Windows с помощью PowerShell 2.0 и 3.0.
В данном посте будут рассмотрены следующие вопросы управления службами Windows:

  • Получаем статус службы на локальном компьютере
  • Получаем статус службы на удаленном компьютере
  • Осуществляем фильтрацию служб (например, остановленные службы)
  • Зависимые службы

Обозначим начальные условия: Вы работаете под Windows 7 и выше и у Вас имеются права администратора. Все команды рекомендуются выполнять в лабораторной или виртуальной среде, перед тем, как применять в “полевых условиях”.

ПОЛУЧАЕМ СТАТУС СЛУЖБЫ

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

PS C:\> get-service

PowerShell, как правило, не чувствителен к регистру. Вывод приведен на скриншоте ниже.

Каждая строка представляет собой объект службы (service object).Каждый сервисный объект, как правило, имеет свои свойства. Вы можете открыть их, просто передав эти объекты в другую команду, Get-Member.

PS C:\> get-service | get-member

Результаты приведены на скриншоте ниже.

Параметр Typename сверху говорит о том, что за объект перед нами; в данном случае это System.ServiceProcess.ServiceController. На скриншоте также обведены свойства объекта. Это атрибуты, которые описывают этот тип объекта. Хотя большинство из них не используются при отображении по умолчанию, вы можете использовать их, если вы их знаете.
Например, нам интересно посмотреть информацию только о Windows Update. Через Get-Service получим информацию только о некоторых ее свойствах.

PS C:\> get-service wuauserv | select Displayname,Status,Can*
DisplayName : Windows Update
Status : Stopped
CanPauseAndContinue : False
CanShutdown : False
CanStop : False

Как я узнал, что могу напечатать имя службы? Посмотрел с помощью Get-Service.
PS C:\> help get-service

Вы можете получить полную справочную информацию, напечатав:

PS C:\> help get-service –full

Информацию о службе можно получить по ее имени или даже начальным буквам имени.

PS C:\> get-service wi*
Status Name DisplayName
------ ---- -----------
Stopped WiaRpc Still Image Acquisition Events
Running WinDefend Windows Defender Service
Running WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se...
Running Winmgmt Windows Management Instrumentation
Running WinRM Windows Remote Management (WS-Manag...

Или если вам удобнее работать с отображаемыми именами, используйте параметр –Displayname.

PS C:\> get-service -DisplayName "windows a*"
Status Name DisplayName
------ ---- -----------
Stopped AllUserInstallA... Windows All-User Install Agent
Running AudioEndpointBu... Windows Audio Endpoint Builder
Running Audiosrv Windows Audio

Я должен использовать имя параметра, чтобы PowerShell воспринимал значения в качестве отображаемого имени, а не фактического имени службы. Команда будет выглядеть так:

PS C:\> get-service "windows a*"

Параметр –Name можно не печатать.

ПОЛУЧАЕМ СТАТУС СЛУЖБЫ НА УДАЛЕННЫХ КОМПЬЮТЕРАХ

До этого нас интересовало получение информации о статусе служб на локальном компьютере. Однако управление службами осуществляется на удаленных компьютерах. Если посмотреть справку по Get-Service, то можно увидеть наличие у этого командлета параметра –Computername. В данном случае подключение к удаленным компьютерам осуществляется без включения функции удаленного управления PowerShell. Если вы можете управлять службами, используя инструменты командной строки (sc.exe или консоль управления Service Manager), вы можете использовать PowerShell. Давайте взглянем на пример:

PS C:\> get-service spooler -ComputerName novo8
Status Name DisplayName
------ ---- -----------
Running spooler Print Spooler

Любая команда, которую я демонстрировал, можно использовать для передачи удаленному компьютеру. Даже нескольким компьютерам, если у вас есть соответствующие права на удаленном компьютере. Если вы используете PowerShell v3, то можно легко выбрать одну службу на множестве компьютеров.

PS C:\> get-service wuauserv -ComputerName chi-dc01,chi-dc02,chi-dc03
Status Name DisplayName
------ ---- -----------
Running wuauserv Windows Update
Stopped wuauserv Windows Update
Running wuauserv Windows Update

Для наглядности представления отформатируем вывод.

PS C:\> get-service wuauserv -ComputerName chi-dc01,chi-dc02,chi-dc03 | format-table Name,Status,Machinename -autosize
Name Status MachineName
---- ------ -----------
wuauserv Running chi-dc03
wuauserv Stopped chi-dc02
wuauserv Running chi-dc01

Тот же самый результат, но в PowerShell v2.

PS C:\> 'chi-dc01','chi-dc02','chi-dc03'| foreach {get-service wuauserv -computername $_} | Format-Table Name,Status,Machinename -AutoSize
Name Status MachineName
---- ------ -----------
wuauserv Running chi-dc01
wuauserv Stopped chi-dc02
wuauserv Running chi-dc03

ОСУЩЕСТВЛЯЕМ ФИЛЬТРАЦИЮ (ИСПОЛЬЗУЯ WHERE-OBJECT)

Фильтрация служб осуществляется с помощью командлета Where-Object (where – сокращение для командлета). Все, что нам нужно от PowerShell в этом случае, так это получить только те службы, у которых статус равен “stopped”.

PS C:\> get-service | where {$_.status -eq 'stopped'}

PowerShell получает информацию обо всех службах и передает их (с помощью “|”) в следующую команду, которая осуществляет просмотр каждого объекта. Если свойство статуса объекта равно “stopped”, она остается в конвейере (pipeline), в противном случае она из него исключается. В конце выражение PowerShell отображает те объекты, которые остались в конвейере.
Результаты приведены ниже.

Теперь давайте попробуем найти одну службу на нескольких машинах. Вывод отформатируем в таблицу.

PS C:\> get-service -computername @('chi-dc01','chi-dc02','chi-dc03') | where {$_.name -eq 'wuauserv'} | format-table Name,Status,Machinename -autosize
Name Status MachineName
---- ------ -----------
wuauserv Running chi-dc02
wuauserv Running chi-dc01
wuauserv Running chi-dc03

Мы даже можем комбинировать запрос отдельных служб с их фильтрацией.

PS C:\> get-service "win*" -comp chi-dc03 | where {$_.status -eq 'running'}
Status Name DisplayName
------ ---- -----------
Running Winmgmt Windows Management Instrumentation
Running WinRM Windows Remote Management (WS-Manag...

Эта команда находит все службы на компьютере CHI-DC03, которые начинаются с ‘WIN’, но отображает только те, которые запущены.
Также можно сгруппировать объекты по свойству статуса (status property).

PS C:\> $dc03 = get-service -computername chi-dc03 | Group-Object -Property Status

Переменная $dc03 является объектом GroupInfo.

PS C:\> $dc03
Count Name Group
----- ---- -----
64 Running {System.ServiceProcess.ServiceController, Sy...
79 Stopped {System.ServiceProcess.ServiceController, Sy...

Свойство Group представляет собой коллекцию связанных служб.

PS C:\> $dc03.Get(0).group

Написанное выше проще понять, если взглянуть на скриншот.

Что касается меня, то я бы предпочел использовать хеш-таблицу.

PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status -AsHashTable
PS C:\> $hash
Name Value
---- -----
Running {System.ServiceProcess.ServiceController, Sys...
Stopped {System.ServiceProcess.ServiceController, Sys...

Теперь каждое имя представляет собой свойство в хеш-таблице. Если у вас имеется опыт работы с PoweShell, вы, возможно, подумываете сделать сделующее:

PS C:\> $hash.running.count

Однако ничего не произойдет. Потому что свойство Status является просто перечислением (enumeration) для [System.ServiceProcess.ServiceControllerStatus] .NET клас и такие свойства, как Running и Stopped представляют собой целые числа. PowerShell осуществляет конвертацию, чтобы представить в более наглядной форме.

PS C:\> $hash = get-service -computername chi-dc03 | Group-Object -Property Status –AsHashTable –AsString

В чем суть параметра –AsString, на мой взгляд, достаточно очевидно. Теперь работать с хеш-таблицей стало проще.

PS C:\> $hash.running.count
62
PS C:\> $hash.running[0..3]
Status Name DisplayName
------ ---- -----------
Running ADWS Active Directory Web Services
Running AppHostSvc Application Host Helper Service
Running BFE Base Filtering Engine
Running BrokerInfrastru... Background Tasks Infrastructure Ser...

Следующей задачей на повестке дня является проверка зависимостей сервера (server dependencies).

Требуемые службы

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

PS C:\> get-service dns -ComputerName chi-dc03 –RequiredServices
Status Name DisplayName
------ ---- -----------
Running Afd Ancillary Function Driver for Winsock
Running Tcpip TCP/IP Protocol Driver
Running RpcSs Remote Procedure Call (RPC)
Running NTDS Active Directory Domain Services

Параметр –RequiredServices передаст объект в конвейер для каждой требуемой службы. Вы можете даже пойти дальше и проверить требуемые службы для работы данной службы.

PS C:\> get-service dns -ComputerName chi-dc03 -RequiredServices | select name,@{name="computername";expression={$_.machinename}} | get-service -RequiredServices
Status Name DisplayName
------ ---- -----------
Running RpcEptMapper RPC Endpoint Mapper
Running DcomLaunch DCOM Server Process Launcher

Параметр –Computername командлета Get-Service возьмет вывод, но только для тех объектов, у которых есть объект свойство Computername – именно поэтому я использую хеш-таблицу с Select-Object. Как мы видим проблем со службой DNS на компьютере CHI-DC03 нет.

ЗАВИСИМЫЕ СЛУЖБЫ

Мы можем сделать то же самое с зависимыми службами. Если таковых не имеется, в конвейер ничего передано не будет.

PS C:\> get-service dns -ComputerName chi-dc03 -DependentServices
PS C:\> get-service lanmanworkstation -ComputerName chi-dc03 -DependentServices
Status Name DisplayName
------ ---- -----------
Stopped SessionEnv Remote Desktop Configuration
Running Netlogon Netlogon
Running Dfs DFS Namespace
Running Browser Computer Browser

Требуемые и зависимые службы также являются частью каждого объекта службы.

PS C:\> get-service rpcss | Select *services
RequiredServices DependentServices
---------------- -----------------
{RpcEptMapper, DcomLaunch} {WwanSvc, wuauserv, WSearch, wscsvc...}

А пока Вы можете получить все зависимости для всех служб, следующая команда

PS C:\> get-service –DependentServices

Это не даст вам особо полезную информацию, поэтому я рекомендую осуществлять запрос по конкретным службам. Команда работает гораздо лучше PowerShell v3.

PS C:\> get-service dns -comp chi-dc01,chi-dc03 -RequiredServices | Sort Machinename,Name | Format-table -GroupBy machinename

Результаты видны на скриншоте ниже.

Чтобы получить подобные результаты в PowerShell v2, вам придется передать имена компьютеров (computernames) в Get-Service.

PS C:\> "chi-dc01","chi-dc03" | foreach { get-service dns -comp $_ -RequiredServices} | Sort Machinename,Name | format-table -GroupBy machinename

В следующей статье будет рассмотрен запуск, остановка и перезапуск служб.
Конец перевода.

Upd:
В посте приведены переводы статей с портала 4sysops.com
Managing Services the PowerShell way – Part 1
Managing Services the PowerShell way – Part 2

P.S. Хотим также поделиться нашей бесплатной программой для управления службами Windows – NetWrix Service Monitor. Программа отслеживает все автоматически запускаемые службы на группе серверов и в случае внезапного сбоя одной или нескольких из них отправляет уведомления по электронной почте. Функция перезапуска гарантирует, что все подконтрольные службы будут работать без простоев. Программа проста в настройке: устанавливаем, вводим имена компьютеров и указываем нужный адрес электронной почты.

С помощью командлета Get-Service можно получить список всех установленных в системе служб, их состояние и тип запуска. Этот и другие командлеты для получения статуса и управления службами Windows впервые появился в версии Powershell 1.0. В этой статье мы разберем типовые примеры использования Get-Service для получения статуса служб на локальном или удаленных компьютерах, типе запуска служб и покажем как определять зависимости служб.

Получить список служб, установленных на локальном или удаленном компьютере можно с помощью командлета Get-Service. Команда Get-Service без параметров возвращает список всех служб на локальной системе.

Get-Service

Данная команда выведет список всех служб и их статус (запущена или остановлена) и отображаемое имя (Display Name).

проверка состояния служб с помощью powershell - Get-Service

Если вам нужно вывести только запушенные службы, воспользуемся такой командой:

Get-Service | Where-Object {$_.Status -EQ "Running"}

Оператор конвейера (|) передает результаты командлету Where-Object, который отбирает только те службы, для которых параметр Status имеет значение Running. В том случае, если нужно вывести только остановленные службы, укажите значение Stopped.

powershell: получаем список запущенных служб в системе

Получить все свойства объекта службы можно с помощью командлета Get-Member.

get-service | get-member

Как вы видите, данный объект имеет тип (Typename) System.ServiceProcess.ServiceController. На скриншоте выведены все доступные свойства и методы объектов служб в системе (большинство из них не используются при отображении по умолчанию).

get-service | get-member

Чтобы вывести определенные свойства службы, нужно воспользоваться возможностями выбора свойств объектов с помощью командлета Select. Например, нам нужно вывести имя, статус и доступные возможности службы Windows Update:

get-service wuauserv | select Displayname,Status,ServiceName,Can*

DisplayName : Windows Update
Status : Stopped
CanPauseAndContinue : False
CanShutdown : False
CanStop : False

получить статус службы из powershell

К примеру, чтобы получить тип запуска служб Windows, выполните команду (работает в PowerShel 5.1):

Get-Service | select -property name,starttype

Можно отфильтровать полученный список по имени службы, используя звездочку как подстановочный знак:

get-service wi*

Так можно отсортировать список служб компьютера в порядке убывания по значению свойства Status. Запущенные службы отображаются раньше остановленных.

get-service s* | sort-object status -Descending

В том случае, если нужно проверить наличие (существование) службы в системе (как правило, это может понадобиться в различных скриптах), вы можете воспользоваться такой конструкцией:

if (Get-Service "ServiceTest" -ErrorAction SilentlyContinue)
{
Write-host "ServiceTest exists"
}

Командлет Get-Service можно использовать для получения статуса служб не только на локальном, но и удаленных компьютерах. Для этого нужно использовать аргумент –Computername. Подключение к удаленным компьютерам осуществляется не через PowerShell Remoting (WinRM), а через службу Service Manager (по аналогии с командой sc.ex).

get-service wuauserv -ComputerName remotePC1

Если вы используете PowerShell v3 или выше, то можно опросить статус службы сразу на множестве удаленных компьютерах, их имена нужно перечислить через запятую.

get-service spooler -ComputerName remotePC1,remotePC2, remotePC3| format-table Name,Status,Machinename –autosize

Командлет format-table используется в данном примере для получения более удобного табличного представления состояния служб.

Командлет Get-Service имеет еще два параметра, которые удобно использовать при администрировании служб. Параметр DependentServices получает службы, которые зависят от данной службы. Параметр RequiredServices получает службы, от которых зависит данная служба.

Приведенная ниже команда выводит список служб, требуемых службе LanmanWorkstation для запуска.

Get-Service -Name LanmanWorkstation –RequiredServices

Get-Service -RequiredServices получаем зависимости служб

Status Name DisplayName
—— —- ————
Running NSI Network Store Interface Service
Running MRxSmb20 SMB 2.0 MiniRedirector
Running Bowser Browser Support Driver

Следующая команда выводит зависимые службы (подробнее о настройке зависимостей служб в Windows), которым требуется служба LanmanWorkstation.

Get-Service -Name LanmanWorkstation -DependentServices

Индивидуальный подход

Доверительные партнерские отношения, подробное изучение сферы деятельности клиентов, особенностей организации их работы позволяют нам четко определять необходимые тактические и стратегические задачи, что поднимает наших партнеров на более высокий уровень среди конкурентов.

Подробнее

Гарантия качеcтва

Выполнение поставленных задач в максимально короткие сроки. Надежность и высокий профессионализм. «Прозрачная» ценовая политика. Предоставление любой информации клиенту, касающейся текущей работы и расходов. Мы полностью отвечаем за качество выполненных работ и соответствие вашим желаниям.

Подробнее

Решение задач любой сложности

Для нас нет ничего невозможного! Реализация любых целей по оригинальным проектам. Все работы выполняются квалифицированными специалистами, регулярно проходящими плановое обучение и аттестацию.

Подробнее

11 сентября 2015

@Echo Off
Set ServiceName=dnscache
:: Получаем состояние службы, проверяем запущена ли
SC queryex %ServiceName%|Find «STATE»|Find «RUNNING»>Nul&&(
rem Попытка остановить
Net stop %ServiceName%>nul||(
rem Если через net stop не вышло остановить, спрашиваем PID
For /F «tokens=3» %%A In (‘SC queryex %ServiceName%^|Find «PID»‘) Do (
rem Завершаем процесс вместе с зависящими службами, используя полученный PID
TaskKill /F /T /PID %%A>nul
rem Задержка для обновления статуса службы после завершения
Ping -n 4 127.0.0.1>nul
)
rem
Net stop %ServiceName% 2>nul
)
)
rem Если служба не была запущена, или уже завершена к тому времени — запускаем её
Net start %ServiceName%

Строим сценарий: шаг за шагом

Часто неполадки в компьютере возникают из-за прекращения работы какой-нибудь службы. Проверить статус служб, чтобы убедиться в их активности, — хороший диагностический прием. На локальной машине можно просто открыть оснастку Computer Management консоли управления Microsoft Management Console (MMC) и заглянуть в раздел Services and Applications, Services. Но как быстро и без хлопот проверить службы на удаленных компьютерах? Если Windows 2000 Server Terminal Services работает в режиме Remote Administration, то можно воспользоваться программой Remote Desktop Connection компании Microsoft, но для этого требуется выполнить подготовительные шаги. Кроме того, данный вариант возможен лишь на компьютерах, принимающих входящие запросы RDP. Лучше — особенно если необходимо провести инвентаризацию большого числа компьютеров — составить сценарий для проверки состояния службы на любом компьютере, совместимом с WMI (Windows Management Instrumentation).

В статье «Сценарии WMI для начинающих» (опубликованной в Windows 2000 Magazine/RE № 5 за 2001 год) я рассказывала о том, как упростить задачи управления компьютером с помощью WMI. Интерфейс WMI обеспечивает доступ ко многим физическим и логическим компонентам компьютера. В данной статье я покажу, как построить сценарий с именем GetServiceStatus.vbs, который устанавливает связь с WMI на сервере и использует его для подготовки списка служб на этой машине. С помощью GetServiceStatus.vbs можно проверить состояние локального сервера, удаленного сервера, группы удаленных серверов или всех серверов домена. Объясняя, как работает GetServiceStatus.vbs, я расскажу о способах организации данных, применении аргументов в сценариях и константах, которые можно использовать для разделения выходных данных символами табуляции и возврата каретки.

Сбор информации о состоянии служб

Основные операции GetService Status.vbs — подключение к конкретному серверу, подготовка списка служб, доступных на этом сервере, и отображение статуса каждой службы. Все остальные действия сценария обеспечивают выбор группы проверяемых серверов.

Для выполнения основных задач я присвоила имя сервера переменной (sComputerName), установила связь с пространством имен WMI на этом сервере и зарегистрировалась с административными полномочиями, чтобы получить нужную информацию. Затем сценарий извлекает полный список всех служб на сервере и отображает имя и текущее состояние каждой службы (например, запущена, остановлена, приостановлена) через символ табуляции. В листинге 1 показано, как сценарий проверяет службы. В этом фрагменте исходного текста жестко задано имя сервера (Alien), но настоящий сценарий является более гибким.

Исходный текст в листинге 1 позволяет пользователю с административными полномочиями в домене установить связь со службой WMI на другой машине, просто указав в переменной sComputerName имя компьютера, на котором предстоит запустить программный код. Для выполнения сценария на удаленном компьютере требуется немного больше времени, чем на локальном, но в локальной сети различие невелико — оно не превышает времени, необходимого для подключения к службе на удаленном компьютере. Машина, на которой выполняется программный код, выдает список всех активных служб. На экране 1 показан фрагмент примера списка.

Однако редактировать сценарий всякий раз при проверке состояния служб на новом компьютере неудобно. Если настроить сценарий на использование в качестве аргументов имен компьютеров, сохраненных в текстовом файле или полученных из Active Directory (AD), то с помощью сценария можно получить отчеты о любых машинах, от конкретного сервера до всех компьютеров, работающих с WMI и способных установить связь со сценарием.

Имена компьютеров как аргументы

Если при каждом запуске сценария вводится лишь несколько имен серверов, то самый простой подход — вводить их по экранному приглашению сценария. Следует помнить, что в VBScript произвольный набор символов, разделенных любым числом пробелов, воспринимается как отдельный аргумент, а аргумент, содержащий пробел, должен быть заключен в кавычки.

Все аргументы VBScript — пронумерованные по порядку начиная с 0 — хранятся в наборе с именем Wscript.Arguments. Пользователь выбирает аргумент из набора, указывая имя набора, за которым следует порядковый номер аргумента в круглых скобках. Таким образом, запись Wscript.Arguments(0) указывает на первый аргумент в наборе, а Wscript.Arguments(3) — на четвертый аргумент. Даже если набор содержит лишь один аргумент, при обращениях к нему из сценария необходимо указать номер этого аргумента. Сценарий не нуждается в специальном коде для получения или сохранения аргументов — GetServiceStatus.vbs присваивает значение аргумента переменной исключительно для того, чтобы было проще работать с ним.

Сценарий принимает входные данные, вводимые пользователем, индексирует данные и сохраняет их в наборе Arguments, как показывает фрагмент исходного текста в листинге 2. Переменной sComputerName поочередно присваивается значение каждого аргумента и выводится имя компьютера, чтобы пользователю было понятно, какой машине соответствуют выводимые данные. Последний сценарий выводит информацию о службах компьютера ниже его имени.

Что произойдет, если имя сервера указано неверно — например, из-за опечатки или потому, что сервер отключен от сети? Это важный вопрос, так как невозможно получить информацию о службах несуществующего компьютера. Пока я просто использовала оператор On Error Resume Next, чтобы сценарий игнорировал любые ошибки и продолжал работу.

Альтернативные способы ввода аргументов

Имена серверов — не единственные аргументы, которые можно ввести в сценарий. Можно указать сценарию источник входных данных, и он будет считывать информацию из текстового файла, содержащего список имен серверов, или проверит все серверы домена. Альтернативный способ — попросить сценарий о помощи. Если пользователь не вводит никаких аргументов, то сценарий может предположить, что имеющиеся аргументы представляют собой имена компьютеров, на которых нужно выполнить сценарий. Как проверить все эти варианты? Пока я просто организую сценарий, чтобы он мог работать по-разному в зависимости от вводимых данных. Позже я покажу, как сценарий производит те или иные действия с этими данными.

Если пользователь не вводит никаких аргументов, то сценарий должен работать на локальном компьютере. Чтобы проверить службы локального компьютера без жесткого указания или ввода имени локального сервера, можно использовать синтаксис WMI. Можно указать текущий компьютер по имени, но можно ввести точку (.), чтобы WMI запустил сценарий на локальной машине. Сценарий работает локально по умолчанию, если настроить его на проверку значения Wscript.Arguments(0) — первого элемента в наборе Arguments. Если элемент пуст, то переменной sComputerName присваивается значение (.).

Еще один вариант — извлечение списка имен серверов из текстового файла. Местонахождение текстового файла должно быть неизменным, чтобы жестко запрограммировать его в сценарии. Однако пользователь должен как-то указать сценарию, что требуется прочитать файл. Для этого можно проверить, не содержится ли в элементе Wscript.Arguments(0) значение file.

Можно настроить сценарий на проверку всех компьютеров в AD или какого-нибудь подмножества компьютеров, заданного в сценарии. Для простоты рассмотрим пример со всеми компьютерами. Чтобы проверить состояние служб на всех компьютерах с интерфейсом WMI, пользователь должен ввести аргумент all. Аналогично можно ввести имя организационной единицы — OU — в качестве аргумента, протестировать входные данные, чтобы убедиться, что это OU, а затем проверить только компьютеры указанной OU.

Поскольку сценарий принимает входные данные различных типов, ему необходимы некоторые дополнительные инструкции. Ранее в моих статьях о сценариях с аргументами не рассматривался случай отсутствия аргументов. Если пользователь, запустивший сценарий, не указал необходимых аргументов, сценарий предупреждал об отсутствии входных данных и прекращал работу. Для данного сценария такой подход неприемлем, так как без аргументов он будет запущен на локальном компьютере. Поэтому я дала пользователю возможность получить подсказку с помощью знакомой команды /?. Если сценарий обнаруживает эту комбинацию символов в элементе Wscript.Arguments(0), то выводит на экран рекомендации по работе со сценарием.

Я уже использовала операторы Select Case во многих статьях, поэтому читателей не должно удивить, что я применяю его в данном сценарии для проверки входных значений. В листинге 3 показан фрагмент сценария, который решает, как интерпретировать входные данные. Сценарий преобразует входные данные в нижний регистр (чтобы избежать противоречий; ALL, All и all — не одинаковые строковые значения), проверяет значение Wscript.Arguments(0) и выполняет программный код в соответствии с этим значением. Очевидно, что окончательная версия сценария будет не просто сообщать о режиме работы сценария, но в листинге 3 показана только общая структура. Теперь у нас есть механизм для ввода другой информации, помимо имен серверов.

Чтение из текстового файла

Если требуется проверить несколько имен серверов или всегда проверять одни и те же серверы, то проще сохранить имена в файле, чем вводить их с клавиатуры при каждом запуске сценария. Если всегда запускать сценарий с одного компьютера, то можно сохранить имена серверов в файле с именем servers.txt (по одному имени сервера в каждой строке), а затем вызвать файл из сценария. Для чтения файла используется COM-объект VBScript с именем File System Object (FSO) — VBScript не знает, как взаимодействовать с файлами, но умеет работать с COM-объектами. Объекты FSO могут представлять папки или файлы; в этом случае FSO используется для выбора и считывания текстового файла, в котором хранятся имена серверов. Имя файла не изменяется, поэтому его можно указать в сценарии как константу, а не как переменную (листинг 4).

Если нужно создать сценарий для чтения файлов из разных источников без редактирования сценария, то можно сделать имя файла первым аргументом, а путь к этому файлу — вторым аргументом. Для этого достаточно сделать значение INPUT_FILE_NAME равным Wscript.Arguments(1), так как в этом аргументе будет храниться путь.

Прежде чем работать со строкой имен, составляющих переменную sComputerName, необходимо составить массив имен. В самой простой и распространенной форме массивы представляют собой таблицы данных из одного столбца, строки которых идентифицируются индексным указателем от 0 до номера последней строки — верхней границы массива. Можно создать массив и заполнить его вручную или создать массив и ввести в него блок существующих данных. При формировании массива из существующих данных следует воспользоваться функцией Split, чтобы разделить содержимое переменной sComputerName на фрагменты с символами возврата каретки/перевода строки (vbCrLf) в качестве разграничителя. Исходный текст, который преобразует содержимое sComputerName в массив aComputers, выглядит следующим образом:

aComputers = Split(sComputerName, vbCrLf)

Сформировав массив, можно обработать данные в нем оператором For Each…Next, чтобы вывести имя каждого компьютера и отобразить его службы вместе с их статусом.

Чтение имен компьютеров из AD

Для полной инвентаризации служб на всех серверах в AD (или части AD) можно прочитать имена непосредственно из контроллера домена (DC) вместо того, чтобы вводить их вручную или считывать из текстового файла. Такой способ связи с серверами гарантирует инвентаризацию только имеющихся в наличии серверов — без потенциальных проблем из-за ошибок при вводе имен — но при этом сильно возрастает объем выходных данных.

Получить список серверов просто: нужно подключиться к службе LDAP (Lightweight Directory Access Protocol — упрощенный протокол доступа к каталогам) на DC, извлечь имена всех компьютеров из AD (или части AD) и поместить эти имена в набор. Затем следует обработать список имен с помощью оператора For Each…Next, получить стандартное имя (common name — CN) каждого компьютера и воспользоваться этой информацией, чтобы выяснить статус служб на каждом компьютере. Например, для запроса к содержимому контейнера Computers используется исходный текст листинга 5. Остальная часть оператора For Each…Next составляет список служб на каждом компьютере и сообщает их статус.

Перенаправление вывода

В листинге 6 показан собранный сценарий, GetServiceStatus.vbs. Этот сценарий может генерировать большой объем данных, поэтому при проверке трех и большего числа серверов я рекомендую не пытаться читать информацию из командного окна. Лучше перенаправить вывод в файл:

getservicestatus.vbs [arguments]


> status.txt

Теперь можно не только проверить состояние служб на локальном или удаленном компьютере, но и предоставить подсказку пользователям сценария, форматировать выходные данные и работать с входными данными различных типов. Эти приемы могут пригодиться и для других сценариев, используемых для подготовки отчетов.


Криста Андерсон — независимый автор и консультант журнала Windows NT Magazine.

С ней можно связаться по адресу: candersn@adelphia.net.

lacostewin

0 / 0 / 0

Регистрация: 22.06.2014

Сообщений: 22

Проверка статуса службы

21.02.2017, 05:58. Показов 46193. Ответов 8

Метки нет (Все метки)


Всем привет.

Подскажите, пожалуйста, что не так в этом скрипте?

Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
@echo off
setlocal 
set service=SNMP
set do=-1
for /f "tokens=1,4" %%i in ('sc query %service%') do ( 
    if "%%i"=="STATE" ( 
        if "%%j"=="RUNNING" (set do=0) else (set do=1) 
   ) 
) 
if %do% EQU 1 net start  %service%
if %do% EQU 0 echo %service% is running!
if %do% EQU -1 echo %service% unknown.
pause

Хотелось бы, что бы если служба не запущена или отсутствует, то выполнялся старт службы. Но, не зависимо от статуса службы я всё равно получаю значение -1. Вывод команд

C:\Program Files\smartmontools\bin>SC queryex snmp

Имя_службы: snmp
Тип : 10 WIN32_OWN_PROCESS
Состояние : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
Код_выхода_Win32 : 0 (0x0)
Код_выхода_службы : 0 (0x0)
Контрольная_точка : 0x0
Ожидание : 0x0
ID_процесса : 2684
Флаги :

C:\Program Files\smartmontools\bin>

и скрипт

SNMP state unknown.
Для продолжения нажмите любую клавишу . . .

Пробовал менять tokens, но увы. Может дело в том, что вывод команды содержит русский шрифт?



0



v_svitere

774 / 423 / 137

Регистрация: 03.06.2009

Сообщений: 1,223

Записей в блоге: 4

21.02.2017, 10:55

lacostewin,
Для управления службами, обязательны админские права, поэтому обязательно, чтобы ваш сценарий выполнялся от учетной записи с админскими правами.

А вообще если у Вас ОС повыше XP могу предложить вариант на powershell

PowerShell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
($status=($service=Get-Service|?{$_.name -eq "snmp"}).status)
if($status -eq "Stopped")
{
    try
        {
            $service.start()
            echo "Служба запущена"
        }
    catch
        {
            echo "Не удалось запустить службу"
        }
}
if($status -eq "Running")
{echo "Сервис Запущен"}



1



6371 / 2196 / 342

Регистрация: 10.12.2013

Сообщений: 7,536

21.02.2017, 15:25

ТС, сделай так, как показал наш товарищ в свитере, и мир станет лучше.

Поясняю.

вот задача:

Сообщение от lacostewin

Хотелось бы, что бы если служба не запущена или отсутствует, то выполнялся старт службы.

а вот то, что волнует ТС после попытки реализации:

Сообщение от lacostewin

Пробовал менять tokens, но увы. Может дело в том, что вывод команды содержит русский шрифт?

Вот какие на хрен токены и шрифты, если речь идёт о запуске/остановке сервиса??

это то, о чём я не устаю толковать — неправильный выбор инструмента полностью разрушил ориентацию ТС.
задача не решена, он теряет время и попросту губит свою молодость, преступно тратит её на ерунду. да-с.

Теперь поднимите глаза и посмотрите на powershell-реализацию-

всё кристально ясно даже пьяной женщине,
всё абсолютно по делу.



1



ZoOoO

226 / 211 / 69

Регистрация: 09.02.2016

Сообщений: 1,040

21.02.2017, 22:04

Windows Batch file
1
2
3
4
5
@echo off
:1
for /f "skip=3 tokens=4" %%i in ('sc query dnscache') do (
if "%%i"=="RUNNING" (echo Служба dnscache запущена&pause&exit /b) else (echo Служба dnscache не запущена&pause&exit /b)
)

Добавлено через 6 минут

Сообщение от lacostewin

Хотелось бы ……….. отсутствует

Если ее нет,то ее вроде и нет?А если запустить,то пропишите команду во вторых скобках в место echo бла бла бла

Windows Batch file
1
sc start dnscache&goto 1

dnscache-это имя службы
Скрипт для отображения русской речи сохранить в 866 кодировке.И запускать через админские права.



0



greg zakharov

Покинул форум

3700 / 1483 / 355

Регистрация: 07.05.2015

Сообщений: 2,903

21.02.2017, 22:23

Сообщение от v_svitere

Для управления службами, обязательны админские права

Для изменения статуса службы — да, для его получения нет. По крайней мере если добрый админ не прикрыл доступ к ветке HKLM\SYSTEM\CurrentControlSet\Services, иными словами, следующий командный сценарий позволит получить статус службы, если дефолтные разрешения на данную ветку не были изменены:

Windows Batch file
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@echo off
  setlocal
    set "i=0"
    for %%i in (%*) do set /a "i+=1"
    if %i% neq 1 echo:=^>err : index is out of range&goto:eof
    set "k=HKLM\SYSTEM\CurrentControlSet\Services"
    for /f "tokens=5 delims=" %%i in (
      '2^>nul reg query %k%'
    ) do (
      if /i "%~1" equ "%%i" (
        for /f "tokens=3" %%j in (
          '2^>nul reg query "%k%\%%i" ^| findstr /irc:"start"'
        ) do set /a "start=%%j"
      )
    )
    if %start% equ 0 echo:Start on boot.
    if %start% equ 1 echo:Start with system.
    if %start% equ 2 echo:Start automatically.
    if %start% equ 3 echo:Manually.
    if %start% equ 4 echo:Disabled.
  endlocal
exit /b

Обзавем наш бат, servchk.cmd, в итоге:

Code
1
2
3
4
5
E:\sandbox> servchk.cmd wuauserv
Start automatically.
 
E:\sandbox> servchk.cmd null
Start with system.

И т.д.



0



226 / 211 / 69

Регистрация: 09.02.2016

Сообщений: 1,040

21.02.2017, 22:30

Сообщение от v_svitere

вариант на powershell

А PS может запустить остановленную службу?Подчеркиваю.Служба у которой стоит не запуск вручную,а отключено.



0



lacostewin

0 / 0 / 0

Регистрация: 22.06.2014

Сообщений: 22

22.02.2017, 10:12

 [ТС]

Сделал так.

Windows Batch file
1
2
3
4
5
6
7
@echo off
sc query "snmp" | find /i "RUNNING"
if not ERRORLEVEL 1 (
    echo service is not running
) else (
    xcopy /y /s /d \\domain.local\SysVol\domain.local\Policies\{111FA9F7-CE3F-444D-B71F-6762FEAC336C}\Machine\Applications\snmp c:\windows\snmp\ 
)

Ну, или net start snmp, но это уже не сильно важно — это всего лишь пример.
Спасибо.



0



v_svitere

774 / 423 / 137

Регистрация: 03.06.2009

Сообщений: 1,223

Записей в блоге: 4

22.02.2017, 10:16

ZoOoO, Да, разумеется.

PowerShell
1
man set-service
PowerShell
1
Set-Service $service.Name -StartupType automatic



0



gtjafar

1 / 1 / 0

Регистрация: 08.11.2019

Сообщений: 2

08.11.2019, 15:30

Одной строкой с помощью логических операндов:

Windows Batch file
1
2
@echo off
sc query "snmp" | find /i "RUNNING" && xcopy /y /s /d \\domain.local\SysVol\domain.local\Policies\{111FA9F7-CE3F-444D-B71F-6762FEAC336C}\Machine\Applications\snmp c:\windows\snmp\ || echo service is not running

Или для удобства чтения кода (в скобки можно еще команд прописать):

Windows Batch file
1
2
3
4
5
6
@echo off
(sc query "snmp" | find /i "RUNNING") && (
xcopy /y /s /d \\domain.local\SysVol\domain.local\Policies\{111FA9F7-CE3F-444D-B71F-6762FEAC336C}\Machine\Applications\snmp c:\windows\snmp\ 
echo successfully) || (
echo service is not running
echo contact your system administrator)



1



BasicMan

Эксперт

29316 / 5623 / 2384

Регистрация: 17.02.2009

Сообщений: 30,364

Блог

08.11.2019, 15:30

Помогаю со студенческими работами здесь

Проверка байт статуса
Напишите программу которая проверяет байт STATUS и переходит к ROUTINE_1, если биты 1, 3 или 5 содержат 1. В противном случае она переходит…

Проверка статуса платежа
Приветствую всех! Прошу помочь мне в моей проблеме! Мне нужно приложение, которое бы проверяла статус платежа. Само приложение хранит…

Проверка статуса olevariant
строю парсер для магазина. сделал модуль, который тянет информацию о характеристиках товара с Никса.

модуль построен так: в webbrowser…

Проверка статуса документа
Доброго времени суток.

Как можно программно запретить перевод документа в режим редактирования (Querymodechange), если после открытия…

Проверка статуса чекбокса
Привет всем!
Искал похожую тему, но не нашел к сожалению.
Подскажите пожалуйста, как на джаве делается проверка статуса чекбокса, т.е…

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:

9

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Как почистить файл winsxs в windows 7
  • Настройка jdk на windows
  • Что такое строка поиска windows
  • Windows defender удалил файл как вернуть
  • Административные шаблоны windows 2019