Перейти к содержимому

Powershell скрипт как служба

  • автор:

Запускаем Powershell скрипт как службу

Картинка блога

Запустить скрипт в большинстве случаев поможет планировщик задач (Task Scheduler). Но предположим, у нас есть PowerShell скрипт, который работает в вечном цикле и/или реагирует на изменения системы в реальном времени. Такая ситуация сложилась со мной сегодня ночью, когда я писал скрипт обновления Secondary DNS на Bind9 из MS DNS.
Чтобы следить за изменениями, как и в обычном C# следует использовать FileWatcher. Вот такой простой скрипт следит за моей пользовательской папкой в вечном цикле:

$localPath = Split-Path -Path $MyInvocation.MyCommand.Definition -Parent #Set-ExecutionPolicy Unrestricted $watcher = New-Object System.IO.FileSystemWatcher $watcher.Path = get-location $watcher.IncludeSubdirectories = $true $watcher.EnableRaisingEvents = $false $watcher.NotifyFilter = [System.IO.NotifyFilters]::LastWrite -bor [System.IO.NotifyFilters]::FileName while($TRUE) < $result = $watcher.WaitForChanged([System.IO.WatcherChangeTypes]::All, 1000); #http://msdn.microsoft.com/en-us/library/t6xf43e0.aspx WatcherChangeTypes #[System.IO.WatcherChangeTypes]::Changed -bor [System.IO.WatcherChangeTypes]::Deleted -bor [System.IO.WatcherChangeTypes]::Renamed -bOr [System.IO.WatcherChangeTypes]::Created, 1000); if($result.TimedOut)< continue; >#Change in + AppData\Roaming\Skype\ousanov\main.db-journal write-host "Change in " + $result.Name . $localPath\yo.ps1 >

Теперь, осталось установить скрипт для работы в качестве службы. Для этого понадобится пара утилит из Windows Server Resource Kit Tools 2003 и права администратора для изменений в реестре. Не торопитесь качать весь пакет, все нужные утилиты я заботливо положил в один архив. В принципе, он содержит все что описано в помощи от MS. Только разнесен по файлам. Так, например Install.bat содержит все что надо для установки сервиса и запуска обновления реестра из файла export.reg. В итоге, установка сводится к изменению путей и названий. Разрешение проблем: Перед тем как ставить службу, вы, возможно, захотите проверить работоспособность. Для этого нужно установить svrany но не импортировать reg файл. В свойствах сервиса можно прописать начальные параметры например: c:\windows\system32\WindowsPowerShell\v1.0\powershell.exe -noexit C:\_shared\powerShell\filewatch\filewatch.ps1 или c:\\windows\\system32\\cmd.exe /k. В моем случае я получил старый добрый «execution of scripts is disbled on this system», лечится с помощью «set-executionpolicy unrestricted».

Автоматизация и ИИ Подписатся на RSS поток Печать

Windows PowerShell — Написание Windows-служб в PowerShell

Windows-службы (Windows Services) — это обычно скомпилированные программы на C, C++, C# или других языках на основе Microsoft .NET Framework, и отладка таких служб бывает весьма трудной. Несколько месяцев назад, вдохновившись тем, что другие операционные системы допускают написание служб как простых скриптов оболочки, я начал интересоваться, есть ли и в Windows более простой способ их создания.

В этой статье представлен конечный результат этих усилий: новый и простой способ создания Windows-служб. Их можно писать на скриптовом языке в Windows PowerShell. Больше никакой компиляции, просто быстрые циклы «правка-тест», которые можно выполнять в любой системе, а не только на компьютере разработчика.

Я предлагаю обобщенный шаблон скрипта службы, PSService.ps1, который позволяет создавать и проверять новые Windows-службы в считанные минуты, используя лишь текстовый редактор наподобие Notepad (блокнота). Этот метод может сэкономить уйму времени и усилий любому, кто хочет поэкспериментировать с Windows-службами или даже предоставлять настоящие Windows-службы, если производительность не является критическим фактором. PSService.ps1 включен в сопутствующий этой статье пакет исходного кода.

Что такое Windows-служба?

Windows-службы — это программы, выполняемые в фоне без взаимодействия с пользователем. Например, веб-сервер, который «молча» отвечает на HTTP-запросы для веб-страниц из сети, является службой, равно как и мониторинговое приложение, просто записывающее показатели производительности или фиксирующее аппаратные события от датчиков.

Службы можно запускать автоматически при загрузке системы. Или запускать по требованию, когда они запрашиваются приложениями, которые полагаются на них. Службы выполняются в собственном сеансе Windows, отличном от UI-сеанса. Они работают в ряде системных процессов с тщательно выбранными правами для ограничения рисков, связанных с безопасностью.

Windows Service Control Manager

Службы управляются Windows Service Control Manager (SCM). SCM отвечает за конфигурирование служб, их запуск и остановку и т. д.

Панель управления SCM доступна через Control Panel | System and Security | Administrative Tools | Services. Как показано на рис. 1, она отображает список всех сконфигурированных служб с их названиями, описаниями, состоянием, типом запуска и именем пользователя.

Windows Service Control Manager GUI в Windows 10

Рис. 1. Windows Service Control Manager GUI в Windows 10

Для SCM также имеются интерфейсы командной строки.

  • Старая утилита net.exe с хорошо известными командами net start и net stop, корнями уходящая аж в MS-DOS! Несмотря на такое название, ее можно использовать для запуска и остановки любой службы, а не только сетевых служб. Введите net help, чтобы получить подробное описание.
  • Более мощная утилита, sc.exe, введенная в Windows NT, дает тонкий контроль над всеми аспектами управления службами. Введите sc /?, чтобы получить подробное описание.

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

Подвох Как net.exe, так и sc.exe используют «короткие» имена служб в одно слово, которые, к сожалению, не совпадают с более описательными названиями, отображаемыми в панели управления SCM. Чтобы получить соответствие между двумя именами, используйте команду get-service из Windows PowerShell.

Состояния службы

Службы могут находиться в разнообразных состояниях. Некоторые состояния обязательны, другие не обязательны. Два базовых состояния, которые должны поддерживаться всеми службами: остановлена (stopped) и запущена (started). Эти состояния соответственно отображаются как пустая ячейка или Running (Выполняется) в столбце Status на рис. 1.

Третье, не обязательное состояние — Paused (Приостановлена). И еще одно неявное состояние, поддерживаемое каждой службой, даже если оно нигде не упоминается, — Uninstalled (Удалена).

Служба может переходить между этими состояниями, как показано на рис. 2.

Состояния службы

Рис. 2. Состояния службы

Наконец, существует несколько переходных состояний, которые службы могут поддерживать (не обязательно): StartPending, StopPending, PausePending, ContinuePending. Они полезны, только если переходы между состояниями занимают значительное время.

Функции управления службами в Windows PowerShell

Windows PowerShell является рекомендуемой оболочкой системного управления со времен Windows Vista. Она включает мощный скриптовый язык и обширную библиотеку функций для управления всеми аспектами ОС. Вот лишь некоторые из сильных сторон Windows PowerShell:

  • согласованные имена функций;
  • полностью объектно-ориентированная;
  • простое управление любым .NET-объектом.

Windows PowerShell предоставляет много функций управления службами, известных как командлеты (cmdlets). Некоторые примеры показаны в табл. 1.

Табл. 1. Функции управления службами в Windows PowerShell

Имя функции Описание
Start-Service Запускает одну или более остановленных служб
Stop-Service Останавливает одну или более выполняемых служб
New-Service Устанавливает новую службу
Get-Service Получает службы на локальном или удаленном компьютере вместе с их свойствами
Set-Service Запускает, останавливает и приостанавливает службу, а также изменяет ее свойства

Чтобы получить полный список всех команд со строкой «service» в их именах, введите:

Get-Command *service* 

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

Get-Command -module Microsoft.PowerShell.Management *service* 

Как это ни удивительно, но в Windows PowerShell нет функции для удаления службы. Это один из редких случаев, когда по-прежнему приходится использовать старую утилиту sc.exe:

sc.exe delete $serviceName 

.NET-класс ServiceBase

Все службы должны создавать .NET-объект, производный от класса ServiceBase. В документации Microsoft описаны все свойства и методы этого класса. В табл. 2 перечислены те из них, которые представляют интерес в данном проекте.

Табл. 2. Некоторые свойства и методы класса ServiceBase

Член Описание
ServiceName Краткое имя, используемое для идентификации службы в системе
CanStop Сообщает, можно ли остановить службу после того, как она запущена
OnStart() Действия, предпринимаемые при запуске службы
OnStop() Действия, предпринимаемые при остановке службы
Run() Регистрирует исполняемый файл службы в SCM

Реализуя эти методы, служба будет управляемой SCM и сможет запускаться автоматически при загрузке системы или по требованию; кроме того, такую службу можно будет запускать или останавливать вручную через панель управления SCM, старыми командами net.exe/sc.exe или новыми функциями Windows PowerShell для управления службами.

Все службы должны создавать .NET-объект, производный от класса ServiceBase.

Создание исполняемого файла из исходного кода на C#, встроенного в скрипт Windows PowerShell

PowerShell упрощает использование .NET-объектов в скриптах. По умолчанию предлагается встроенная поддержка многих типов .NET-объектов, достаточная для большинства задач. Еще лучше то, что она является расширяемой и позволяет встраивать короткие фрагменты C#-кода в скрипт Windows PowerShell для добавления поддержки любой другой .NET-функциональности. Эта возможность обеспечивается командой Add-Type, которая, несмотря на свое название, может делать гораздо больше, чем просто добавлять поддержку новых типов .NET-объектов в Windows PowerShell. Она позволяет даже компилировать и связывать полное C#-приложение в новый исполняемый файл. Например, следующий скрипт Windows PowerShell, hello.ps1:

$source = @" using System; class Hello < static void Main() < Console.WriteLine("Hello World!"); >> "@ Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly "hello.exe" -OutputType ConsoleApplication 

создаст приложение hello.exe, которое выводит в консоль «Hello world!»:

PS C:\Temp> .\hello.ps1 PS C:\Temp> .\hello.exe Hello World! PS C:\Temp> 

Собираем все воедино

Возможности PSService.ps1 На основе всего того, что мы обсудили на данный момент, я могу создать ту службу Windows PowerShell, о которой я мечтал, — скрипт PSService.ps1, который:

  • может сам себя устанавливать и удалять (используя функции Windows PowerShell для управления службами);
  • может сам себя запускать и останавливать (используя тот же набор функций);
  • включает короткий фрагмент C#-кода, создающий PSService.exe для SCM (с помощью команды Add-Type);
  • делает обратный вызов из заглушки PSService.exe в скрипт PSService.ps1 для выполнения реальной операции службы (в ответ на события OnStart, OnStop и др.);
  • управляется из панели SCM и всех утилит командной строки (благодаря заглушке PSService.exe);
  • является отказоустойчивым и успешно обрабатывает любую команду, находясь в любом состоянии. Например, он может автоматически остановить службу перед ее удалением или ничего не делать, если ему поступит запрос запустить уже выполняемую службу;
  • поддерживает Windows 7 и все более поздние версии Windows (используя функциональность только Windows PowerShell v2).

Заметьте, что в этой статье я затронул лишь критически важные части проекта и реализации PSService.ps1. Скрипт-пример также содержит отладочный код и в какой-то мере поддерживает необязательную функциональность служб, но их описание здесь усложнило бы пояснения безо всякой необходимости.

Архитектура PSService.ps1 Скрипт организуется в серию разделов:

  • комментарий-заголовок, описывающий файл;
  • справочный блок в виде комментариев;
  • блок Param, определяющий ключи командной строки;
  • глобальные переменные;
  • вспомогательные процедуры: Now и Log;
  • блок исходного кода на C# для создания заглушки PSService.exe;
  • основную процедуру, обрабатывающую все ключи командной строки.

Глобальные переменные

Непосредственно за блоком Param скрипт PSService.ps1 содержит глобальные переменные, определяющие глобальные настройки, которые при необходимости можно изменять. Их значения по умолчанию приведены в табл. 3.

Табл. 3. Значения по умолчанию глобальных переменных

Переменная Описание Значение по умолчанию
$serviceName Однословное имя, используемое командами net start и другими Базовое имя скрипта
$serviceDisplayName Более описательное название службы Sample PowerShell Service
$installDir Куда устанавливаются файлы службы $\System32
$logFile Имя файла, в который записываются сообщения службы $\Logs\­$serviceName.log
$logName Имя журнала событий, в который записываются события службы Application

Используя базовое имя файла как имя службы (например, PSService для PSService.ps1), вы можете создавать несколько служб из одного и того же скрипта простым копированием этого скрипта, переименованием копии и последующей установкой копии.

Аргументы командной строки

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

Табл. 4. Аргументы командной строки для переходов состояний

Ключ Описание
-Start Запуск службы
-Stop Остановка службы
-Setup Установка себя как службы
-Remove Удаление службы

(Поддержка состояния paused [приостановлена] не реализована, но ее легко добавить, используя соответствующий ключ для перехода в это состояние.)

В табл. 5 показано еще несколько аргументов для управления, поддерживаемых скриптом.

Табл. 5. Поддерживаемые аргументы для управления

Ключ Описание
-Restart Остановка службы и ее повторный запуск
-Status Отображение текущего состояния службы
-Service Запуск экземпляра службы (только для применения заглушкой service.exe)
-Version Отображение версии службы
Общие параметры –? , –Verbose , –Debug и т. д.

Каждый ключ перехода состояния имеет два режима работы.

  • При вызове конечным пользователем С помощью функций управления службами в Windows PowerShell для инициации перехода состояния.
  • При вызове из SCM (косвенно, через заглушку service.exe) Соответствующее управление экземпляром службы service.ps1.

Эти два случая можно различить в период выполнения, проверив имя пользователя: в первом случае это обычный пользователь (системный администратор), а во втором — реальный системный пользователь Windows. Системного пользователя можно идентифицировать примерно так:

$identity = [Security.Principal.WindowsIdentity]::GetCurrent() $userName = $identity.Name # Ex: "NT AUTHORITY\SYSTEM" # or \"Domain\Administrator\" $isSystem = ($userName -eq "NT AUTHORITY\SYSTEM") 

Установка

Цель установки службы — сохранить копию ее файлов в локальном каталоге и объявить SCM об этом, чтобы тот знал, какую программу следует выполнить для запуска службы.

Вот последовательность операций, выполняемых при обработке ключа –Setup.

  1. Удаление любого предыдущего экземпляра, если таковой есть.
  2. Создание каталога установки, если требуется. (Этого не нужно при использовании каталога по умолчанию: C:\Windows\System32.)
  3. Копирование скрипта службы в каталог установки.
  4. Создание заглушки service.exe в том же каталоге установки на основе фрагмента C#-кода в скрипте.
  5. Регистрация службы.

Заметьте, что, начав с единственного исходного скрипта Windows PowerShell (PSService.ps1), я получил в итоге три файла, установленных в C:\Windows\System32: PSService.ps1, PSService.pdb и PSService.exe. Эти три файла понадобится удалить при удалении службы. Для реализации установки включите две части кода в скрипт.

  • Определение ключа –Setup в блоке Param в начале скрипта:
[Parameter(ParameterSetName='Setup', Mandatory=$true)] [Switch]$Setup, # Install the service 
  • Блок if (рис. 3) для обработки ключа –Setup в основной процедуре в конце скрипта.

Рис. 3. Обработчик кода установки

if ($Setup) < # Установка службы # Проверяем, нужно ли это (служба не установлена или # этот скрипт новее установленной копии). [. ] # Если нужно и уже установлена, удаляем старую копию. # Копируем скрипт службы в каталог установки. if ($ScriptFullName -ne $scriptCopy) < Copy-Item $ScriptFullName $scriptCopy ># Генерируем EXE-файл службы из исходного C#-кода, # встроенного в этот скрипт try < Add-Type -TypeDefinition $source -Language CSharp -OutputAssembly $exeFullName -OutputType ConsoleApplication -ReferencedAssemblies "System.ServiceProcess" >catch < $msg = $_.Exception.Message Write-error "Failed to create the $exeFullName service stub. $msg" exit 1 ># Регистрируем службу $pss = New-Service $serviceName $exeFullName -DisplayName $serviceDisplayName -StartupType Automatic return > 

Запуск

За управление службами отвечает SCM. Каждая операция запуска должна проходить через SCM, чтобы он мог отслеживать состояния служб. Поэтому, даже если пользователь хочет вручную инициировать запуск через скрипт службы, этот запуск должен быть выполнен как запрос к SCM. В этом случае последовательность операция перечислена ниже.

  1. Пользователь (администратор) запускает первый экземпляр: PSService.ps1 –Start.
  2. Этот первый экземпляр сообщает SCM запустить службу: Start-Service $serviceName.
  3. SCM выполняет PSService.exe. Ее процедура Main создает объект службы, а затем вызывает его метод Run.
  4. SCM вызывает метод OnStart объекта службы.
  5. C#-метод OnStart запускает второй экземпляр скрипта: PSService.ps1 –Start.
  6. Этот второй экземпляр, теперь выполняемый в фоне как системный пользователь, запускает третий экземпляр, который останется в памяти как настоящая служба: PSService.ps1 –Service. Этот экземпляр и работает как служба.

В итоге будут выполняться две задачи: PSService.exe и экземпляр PowerShell.exe, выполняющий PSService.ps1 –Service.

За управление службами отвечает SCM.

Все это реализуется тремя частями кода в скрипте.

  • Определение ключа –Start в блоке Param в начале скрипта:
[Parameter(ParameterSetName='Start', Mandatory=$true)] [Switch]$Start, # Запуск сервиса 
  • В процедуре Main в конце скрипта блок if обрабатывает ключ –Start:
if ($Start) else < # Вызвана вручную администратором Start-Service $serviceName # Просим SCM запустить ее >return > 
  • Фрагмент исходного кода на C#, процедура Main и обработчик для OnStart, который выполняет команду PSService.ps1 –Start, как показано на рис. 4.

Рис. 4. Обработчик стартового кода

public static void Main() < System.ServiceProcess.ServiceBase.Run(new $serviceName()); >protected override void OnStart(string [] args) < // Запускаем дочерний процесс с другой копией этого скрипта try < Process p = new Process(); // Перенаправляем поток вывода дочернего процесса p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.StartInfo.FileName = "PowerShell.exe"; p.StartInfo.Arguments = "-c & '$scriptCopyCname' -Start"; p.Start(); // Сначала считываем поток вывода, а затем ждем. // (Предлагается во избежание взаимоблокировок.) string output = p.StandardOutput.ReadToEnd(); // Ждем завершения стартового кода скрипта, // который запускает экземпляр -Service p.WaitForExit(); >catch (Exception e) < // Протоколируем сбой >> 

Получение состояния службы

Обработчик –Status просто запрашивает у SCM состояние службы и передает его в конвейер вывода:

try < # Не выполняется, если служба не установлена $pss = Get-Service $serviceName -ea stop >catch < "Not Installed" return >$pss.Status 

Но на этапе отладки вы можете столкнуться со сбоями скрипта, например из-за синтаксических ошибок в скрипте и т. п. В таких случаях состояние SCM может оказаться в конечном счете некорректным. Я попадал в такую ситуацию несколько раз, когда готовил эту статью. Чтобы помочь в диагностике такого рода проблем, целесообразно все перепроверять и провести поиск экземпляров –Service:

$spid = $null $processes = @(gwmi Win32_Process –filter "Name = 'powershell.exe'" | where < $_.CommandLine -match ".*$scriptCopyCname.*-Service" >) foreach ($process in $processes)

Остановка и удаление

Операции Stop и Remove, по сути, отменяют то, что было сделано операциями Start и Setup соответственно:

  • –Stop (при запуске пользователем) сообщает SCM остановить службу;
  • при запуске системой экземпляр PSService.ps1 –Service просто уничтожается;
  • –Remove останавливает службу, отменяет ее регистрацию, используя sc.exe delete $serviceName, а затем удаляет файлы в каталоге установки.

Кроме того, их реализация очень похожа на таковую для Setup и Start.

  1. Определение каждого ключа в блоке Param в начале скрипта.
  2. Блок if обрабатывает ключ в процедуре Main в конце скрипта.
  3. Для операции Stop в C#-фрагменте имеется обработчик для OnStop, который запускает PSService.ps1 –Stop. Операция Stop работает по-разному в зависимости от типа пользователя — реального или системного.

Запись событий в журнал

Службы выполняются в фоновом режиме без UI. Это затрудняет их отладку: как диагностировать, что именно сбоит, когда по своей природе они ничего не отображают? Обычный метод — вести запись всех сообщений об ошибках с временными метками, а также протоколировать важные события, прошедшие успешно, например переходы состояний.

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

Скрипт-пример PSService.ps1 реализует два разных метода протоколирования и использует их обоих в стратегически важных точках (включая ранее показанные фрагменты кода, где эти методы были убраны, чтобы сделать понятнее базовые операции).

  • Один из методов записывает в журнал Application объекты событий с именем службы в качестве имени источника, как показано на рис. 5. Эти объекты событий видны в Event Viewer, и их можно фильтровать и искать, используя все средства этой утилиты. Вы также можете получить эти записи с помощью командлета Get-Eventlog:
Get-Eventlog -LogName Application -Source PSService | select -First 10 
  • Другой метод записывает строки сообщений в текстовый файл в каталоге Windows Logs, $\Logs\$serviceName.log (рис. 6). Этот файл журнала можно читать в блокноте, и вести по нему поиск с помощью findstr.exe или Win32-портов grep, tail и т. д.

Просмотр событий PSService

Рис. 5. Просмотр событий PSService

Рис. 6. Пример файла журнала

PS C:\Temp> type C:\Windows\Logs\PSService.log 2016-01-02 15:29:47 JFLZB\Larvoire C:\SRC\PowerShell\SRC\PSService.ps1 -Status 2016-01-02 15:30:38 JFLZB\Larvoire C:\SRC\PowerShell\SRC\PSService.ps1 -Setup 2016-01-02 15:30:42 JFLZB\Larvoire PSService.ps1 -Status 2016-01-02 15:31:13 JFLZB\Larvoire PSService.ps1 -Start 2016-01-02 15:31:15 NT AUTHORITY\SYSTEM & 'C:\WINDOWS\System32\PSService.ps1' -Start 2016-01-02 15:31:15 NT AUTHORITY\SYSTEM PSService.ps1 -Start: Starting script 'C:\WINDOWS\System32\PSService.ps1' -Service 2016-01-02 15:31:15 NT AUTHORITY\SYSTEM & 'C:\WINDOWS\System32\PSService.ps1' -Service 2016-01-02 15:31:15 NT AUTHORITY\SYSTEM PSService.ps1 -Service # Beginning background job 2016-01-02 15:31:25 NT AUTHORITY\SYSTEM PSService -Service # Awaken after 10s 2016-01-02 15:31:36 NT AUTHORITY\SYSTEM PSService -Service # Awaken after 10s 2016-01-02 15:31:46 NT AUTHORITY\SYSTEM PSService -Service # Awaken after 10s 2016-01-02 15:31:54 JFLZB\Larvoire PSService.ps1 -Stop 2016-01-02 15:31:55 NT AUTHORITY\SYSTEM & 'C:\WINDOWS\System32\PSService.ps1' -Stop 2016-01-02 15:31:55 NT AUTHORITY\SYSTEM PSService.ps1 -Stop: Stopping script PSService.ps1 -Service 2016-01-02 15:31:55 NT AUTHORITY\SYSTEM Stopping PID 34164 2016-01-02 15:32:01 JFLZB\Larvoire PSService.ps1 -Remove PS C:\Temp> 

Функция Log упрощает запись таких сообщений, автоматически предваряя их временными метками по стандарту ISO 8601 и именем текущего пользователя:

Function Log ([String]$string) < if (!(Test-Path $logDir)) < mkdir $logDir >"$(Now) $userName $string" | out-file -Encoding ASCII -append "$logDir\$serviceName.log" > 

Пример тестового сеанса

Вот как были сгенерированы предыдущие журналы:

PS C:\Temp> C:\SRC\PowerShell\SRC\PSService.ps1 -Status Not Installed PS C:\Temp> PSService.ps1 -Status PSService.ps1 : The term 'PSService.ps1' is not recognized as the name of a cmdlet, function, script file, or operable program. [. ] PS C:\Temp> C:\SRC\PowerShell\SRC\PSService.ps1 -Setup PS C:\Temp> PSService.ps1 -Status Stopped PS C:\Temp> PSService.ps1 -Start PS C:\Temp> 

Это показывает, как в принципе использовать службу. Учтите, что эти команды должны выполняться пользователем с правами локального администратора в сеансе Windows PowerShell, работающем под учетной записью Administrator. Заметьте, что скрипт PSService.ps1 сначала отсутствовал в пути, но появился после выполнения операции –Setup. (Первый вызов –Status без пути заканчивается неудачей;, а второй вызов –Status завершается успешно.)

Скрипт службы, написанный в Windows PowerShell, очень удобен для проверки концепции.

Вызов PSService.ps1 –Status на этом этапе даст вывод: Running. А через 30 секунд ожидания вы получите: PS C:\Temp> PSService.ps1 -Stop PS C:\Temp> PSService.ps1 -Remove PS C:\Temp> 

Адаптация службы

Чтобы создать собственную службу, просто сделайте следующее.

  • Скопируйте службу-пример в новый файл с новым базовым именем, например C:\Temp\MyService.ps1.
  • Измените длинное название службы в разделе глобальных переменных.
  • Замените блок TO DO в обработчике –Service в конце скрипта. На данный момент блок while ($true) просто содержит макетный код, который пробуждается через каждые 10 секунд и записывает в файл журнала одно сообщение:
####### TO DO: Implement your own service code here. ######## #### Example that wakes up and logs a line every 10 sec: #### Start-Sleep 10 Log "$script -Service # Awaken after 10s" 
  • Установите и приступайте к тестированию:
C:\Temp\MyService.ps1 –Setup MyService.ps1 –Start type C:\Windows\Logs\MyService.log 

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

Ограничения и проблемы

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

Пример скрипта работает в Windows версий от XP до 10 и в соответствующих серверных версиях. В Windows XP вы должны установить Windows PowerShell v2, который по умолчанию отсутствует. Скачайте и установите Windows Management Framework v2 for XP (bit.ly/­1MpOdpV), включающую Windows PowerShell v2. Заметьте, что я очень мало тестировал в этой ОС, поскольку она больше не поддерживается.

Во многих системах выполнение скриптов Windows PowerShell запрещено по умолчанию. Если вы получаете ошибку наподобие «выполнение скриптов отключено в этой системе» при попытке запустить PSService.ps1, то используйте:

Set-ExecutionPolicy RemoteSigned 

Более подробные сведения см. во врезке «Ссылки».

Очевидно, такой скрипт службы, как этот, не может сравниться по производительности с компилированной программой. Скрипт службы, написанный в Windows PowerShell, очень удобен для проверки концепции и для задач с низкими издержками в отношении производительности вроде мониторинга системы, кластеризации служб и т. д. Но для любой высокопроизводительной задачи рекомендуется переписать службу на C++ или C#.

Кроме того, объем занимаемой памяти превышает таковой у скомпилированной программы, так как требует загрузки полнофункционального интерпретатора Windows PowerShell в сеансе System. Но в современных компьютерах со многими гигабайтами памяти это не имеет особого значения.

Этот скрипт не имеет абсолютно никакого отношения к Ps­Service.exe от Марка Руссиновича (Mark Russinovich). Я выбрал имя PSService.ps1 до того, как узнал о совпадении имен. В конечном счете я сохранил имя скрипта-примера таким, поскольку оно делает понятным предназначение скрипта. Конечно, если вы планируете поэкспериментировать со своей службой на основе Windows PowerShell, то должны переименовать его, чтобы получить уникальное имя службы из уникального базового имени скрипта!

Ссылки

  • Введение в Windows-службы (bit.ly/1UOBJJY);
  • Как создавать Windows-службы (bit.ly/1VJCnJo);
  • Класс ServiceBase (bit.ly/1UOC13y);
  • Управление службами (bit.ly/1VJCZyG);
  • Как отлаживать Windows-службы (bit.ly/1RjEhPg).

Жан-Франсуа Лавуа (Jean-François Larvoire) работает на Hewlett-Packard Enterprise в Гренобле (Франция). В течение более 30 лет занимается разработкой программного обеспечения для BIOS персональных компьютеров, драйверов для Windows и для системного управления Windows и Linux. С ним можно связаться по адресу jf.larvoire@hpe.com.

Выражаю благодарность за рецензирование статьи эксперту JDH IT Solutions Джеффри Хиксу (Jeffery Hicks).

Блог Сисадмина

Полезная информация об администрировании пользовательских и серверных ОС Windows.

Запуск PowerShell скрипта в автозагрузке Windows 10

Сначала в локальной политике безопасности необходимо включить возможность запуска не подписанных скриптов. Для этого запускаем cmd от имени администратора, оттуда запускаем gpedit (или сразу запускаем gpedit.msc через «Выполнить»). Затем идем сюда:

Конфигурация компьютера — Административные шаблоны — Компоненты Windows — Windows Powershell. Нажимаем два раза на «Включить выполнение скриптов». Выбираем «Включить», и ниже «Разрешить все».

Затем создаем cmd файл в любой папке, например C:\script\ics.cmd, такого содержания:

Где ics_reenable.ps1 — сам powershell скрипт.

И создаем в планировщике задачу, с триггером «включение компьютера» или «вход в систему».

Также при необходимости ставим галочки «запускать с наивысшими правами» и «запускать независимо от входа пользователя в систему».

Запись опубликована 28.03.2019 автором alex в рубрике Windows 10.

Запуск PowerShell скрипта в автозагрузке Windows 10 : 2 комментария

  1. Alex04.04.2019 в 19:27 Вопрос. Почему может не отрабатывать скрипт PowerShell из планировщика задач, если в действие указан сетевой путь? Прав хватает, ExecutionPolicy вроде тоже.

Управление службами Windows с помощью PowerShell

date

27.07.2020

user

itpro

directory

PowerShell, Windows 10, Windows Server 2016

comments

комментариев 12

В Windows вы можете управлять службами не только из графической консоли services.msc или утилиты командной строки Sc.exe (первоначальна включалась в пакет ресурсов Resource Kit), но и с помощью PowerShell. В этой статье мы смотрим различные сценарии управления службами Windows с помощью PowerShell.

Основные командлеты PowerShell для управления службами Windows

Существует восемь основных командлетов Service, предназначенных для просмотра состояния и управления службами Windows.

Чтобы получить весь список командлетов Service, введите команду:

управление службами windows из powershell

  • Get-Service — позволяет получить службы на локальном или удаленном компьютере, как запущенные, так и остановленные;
  • New-Service – создать службу. Создает в реестре и базе данных служб новую запись для службы Windows;
  • Restart-Service – перезапустить службу. Передает сообщение об перезапуске службы через Windows Service Controller
  • Resume-Service – возобновить службы. Отсылает сообщение о возобновлении работы диспетчеру служб Windows;
  • Set-Service — изменить параметры локальной или удаленной службы, включая состояние, описание, отображаемое имя и режим запуска. Этот командлет также можно использовать для запуска, остановки или приостановки службы;
  • Start-Service – запустить службу;
  • Stop-Service – остановить службу (отсылает сообщение об остановке диспетчеру служб Windows);

Получить подробное описание и примеры использования конкретного командлета можно через Get-help:

Get-Help Start-Service

Get-Service: получаем список служб и их состояние

Получить список и состояние (Running/Stopped) службы на локальном или удаленном компьютере можно с помощью командлета Get-Service. Параметр -Name позволяет делать отбор по имени службы. Имя службы можно задать с использованием подстановочного символа *.

Get-Service просмотр состояния служб

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

Get-Service поиск по имени службы

.

Командлет Get-Service можно использовать для получения состояния служб на удаленных компьютерах, указав параметр -ComputerName. Можно опросить статус службы сразу на множестве удаленных компьютеров, их имена нужно перечислить через запятую. Например, приведенная ниже команда получает состояние службы Spooler на удаленных компьютерах RM1 и RM2.

Get-Service spooler –ComputerName RM1,RM2

Status Name DisplayName ------ ---- ----------- Running spooler Print Spooler Stopped spooler Print Spooler

Вывести все свойства службы позволит командлет Select-Object:

Get-Service spooler | Select-Object *

вывести все свойства службы windows

Командлет Select-Object позволит вывести определенные свойства службы. Например, нам нужно вывести имя, статус и доступные возможности службы Spooler:

Get-Service Spooler | Select DisplayName,Status,ServiceName,Can*

Get-Service - можно ли перезапускать, приостаналивать службу windows

Командлет Get-Service имеет два параметра, которые позволяют получить зависимости служб:

  • Параметр -DependentServices позволяет вывести службы, которые зависят от данной службы;
  • Параметр -RequiredServices позволяет вывести службы, от которых зависит данная служба.

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

Get-Service –Name Spooler -RequiredServices

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

Следующая команда выводит службы, которые зависят от службы Spooler:

Get-Service –Name Spooler -DependentServices

Get-Service DependentServices

При необходимости найти службы с определенным состоянием или параметрами, используйте командлет Where-Object. Например, получим список запущенных служб со статусом Running:

Get-Service | Where-Object status -eq

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

Get-Service | Where-Object <<img decoding=

.starttype -eq » width=»» />.starttype -eq » width=»» />

Проверить, что в системе имеется указанная служба:

if (Get-Service «ServiceTest» -ErrorAction SilentlyContinue)

<
Write-host «ServiceTest exists»
>

Остановка, запуск, приостановка и перезапуск служб из PowerShell

Остановить службу можно с помощью командлета Stop-Service. Чтобы остановить службу печати, выполните команду:

Stop-Service -Name spooler

Командлет Stop-Service не выводит никаких данных после выполнения. Чтобы увидеть результат выполнения команды, используйте параметр -PassThru.

Командлет Stop-Service - остановит службу

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

Cannot stop service because it has dependent services. It can only be stopped if force flag set.

Stop-Service - ошибка Cannot stop service because it has dependent services. It can only be stopped if force flag set

Для принудительной остановки используйте параметр –Force. Вы должны помнить, что остановятся также все зависимые службы:

Stop-Service samss –Force -Passthru

Следующая команда остановит перечисленные службы (bits,spooler) со статусом ”Running”:

get-service bits,spooler | where | stop-service –passthru

остановить несколько служб из powershell

Иногда службы зависают в статусе Stopping и их процессы приходится завершать принудительно.

Командлет Start-Service запускает остановленные службы:

Start-Service -Name spooler -PassThru

Start-Service -запуск службы

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

get-service samss | Foreach

Start-Service запустить службу и все зависимые службы

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

Get-Service samss | Format-List name, canpauseandcontinue

Get-Service canpauseandcontinue

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

список служб, разрешающих приостановку

Приостановим службу SQLBrowser:

Suspend-Service -Name SQLBrowser

Suspend-Service

Для возобновления работы приостановленной службы служит командлет Resume-service:

Resume-Service -Name SQLBrowser

Resume-Service

Следующая команда возобновляет работу всех приостановленных служб:

get-service | where-object | resume-service

Командлет Restart-Service перезапускает службу:

Restart-Service -Name spooler

Restart-Service - перезапуск службы windows

Эта команда запускает все остановленные сетевые службы компьютера:

get-service net* | where-object | restart-service

Параметр —ComputerName у этих командлетов отсутствует, но их можно выполнить на удаленном компьютере с помощью командлета Invoke-Command или через пайп:

Например, чтобы перезапустите очередь печати на удаленном компьютере RM1, выполните команду:
Get-Service Spooler -ComputerName RM1 | Start-Service

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

Set-Service – изменение настроек службы Windows

Командлет Set-Service позволяет изменить параметры или настройки служб на локальном или удаленном компьютере. Так как состояние службы является свойством, этот командлет можно использовать для запуска, остановки и приостановки службы. Командлет Set-Service имеет параметр -StartupType, позволяющий изменять тип запуска службы.

Изменим тип запуска службы spooler на автоматический:

Set-Service spooler –startuptype automatic –passthru

Set-Service включить автозапуск для службы

Можно перевести службу на ручной (manual) запуск:

Set-Service spooler –startuptype manual –passthru

ручной запуск службы

Создание и удаление служб Windows c помощью PowerShell

New-Service – командлет для создания новой службы в Windows. Для новой службы требуется указать имя и исполняемый файл (вы можете запустить PowerShell скрипт как службу Windows).

В примере создадим новую службу с именем TestService.

new-service -name TestService -binaryPathName «C:\WINDOWS\System32\svchost.exe -k netsvcs»

New-Service создать новую службу в windows

С помощью параметра Get-WmiObject получим информацию о режиме запуска и описание службы

get-wmiobject win32_service -filter «name=’testservice'»

get-wmiobject win32_service -filter

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

Set-Service -Name TestService -Description ‘My Service’ -StartupType Manual

Set-Service - изменить тип запуска службы

Чтобы удалить службу используйте команду

(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.GetMethodParameters

$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 аккаунта. Пароль при этом не указывается.

Invoke-WmiMethod - запуск службы из под другого пользователя

Как видите, PowerShell позволяет легко управлять службами Windows. Можно создавать, останавливать, запускать и возобновлять службы, менять их свойства. Большинство командлетов позволяют управлять службами на удаленных компьютерах.

Предыдущая статьяПредыдущая статья Следующая статья Следующая статья

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *