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

от admin

Running PowerShell Script (*.PS1) as a Windows Service

Any PowerShell script can be transformed to a real Windows service that runs in the background and starts automatically during your server boot. You can create a Windows service using srvany.exe or instsrv.exe tools (from Windows Server Resource 2003 Kit) which allow you to run the powershell.exe process with a parameter that contains the path to your PS1 script file.

The main disadvantage of creating a service using this method is that srvany.exe does not control a PowerShell script execution state, and if the app crashes (hangs up), the service does not see it and goes on working. To create a Windows service from a file that contains a PowerShell script, in this article we will use the NSSM (Non-Sucking Service Manager) toolkit, which does not demonstrate the above mentioned disadvantages.

You can download and install NSSM manually or using Chocolatey. Firstly, install Choco itself:

Set-ExecutionPolicy Bypass -Scope Process -Force; `
iex ((New-Object System.Net.WebClient).DownloadString(‘https://chocolatey.org/install.ps1’))

Then install the NSSM package:

choco install nssm

In this example, we will track the changes in a specific Active Directory group in real time and inform a security administrator using a pop-up notification and e-mail (the script is given in this article) .

So, we have a PowerShell code that needs to be saved as a PS1 file. Let’s add an infinite loop that performs a check every minute:

while($true) <
#Your PS code
Start-Sleep –Seconds 60
>

You can create a service from a PowerShell script using NSSM directly from PowerShell:

$NSSMPath = (Get-Command «C:\ps\nssm\win64\nssm.exe»).Source
$NewServiceName = “CheckADGroup”
$PoShPath= (Get-Command powershell).Source
$PoShScriptPath = “C:\ps\CheckADGroup\checkad.ps1”
$args = ‘-ExecutionPolicy Bypass -NoProfile -File «<0>«‘ -f $PoShScriptPath
& $NSSMPath install $NewServiceName $PoShPath $args
& $NSSMPath status $NewServiceName

Check the service status in PowerShell:

So you have created and started your new Windows service. Make sure that it has appeared in the services management console (services.msc).

CheckADGroup has appeared, it is configured to start automatically and is currently running. As you can see, your PowerShell script is running inside the nssm.exe process.

windows service from a powershell script using nnm

In order the service can show notifications in a user session enable the Allow service to interact with desktop option on the Log on tab.

Start-Service -Name ui0detect

However, Interactive Services Detection Service has been completely removed from Windows 10 build 1803, and you won’t be able to switch to Session 0. So you won’t see the notification windows displayed under System account.

You can change the service description using this command:

& $NSSMPath set $NewServiceName description “Monitoring of AD group changes”

Запуск PowerShell скрипта как службы Windows

date03.06.2020
useritpro
directoryPowerShell
commentsкомментариев 6

Из любого скрипта 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:

Set-ExecutionPolicy Bypass -Scope Process -Force; `
iex ((New-Object System.Net.WebClient).DownloadString(‘https://chocolatey.org/install.ps1’))

Затем установим пакет NSSM:

choco install nssm

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

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

while($true) <
#Ваш PS код
Start-Sleep –Seconds 60
>

Создать службу из скрипта 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 «<0>«‘ -f $PoShScriptPath
& $NSSMPath install $NewServiceName $PoShPath $args
& $NSSMPath status $NewServiceName

Запустим новую службу:

NSSM - создать службу Windows из скрипта PowerShell

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

Служба CheckADGroupSrv действительно появилась, она настроена на автоматический запус и в данный момент запущена (Running). Как вы видите, ваш PowerShell скрипт запущен внутри процесса nssm.exe.

Чтобы служба могла отображать уведомления в сеанс пользователя (взаимодействовать с рабочим столом) нужно на вкладке “Вход в систему” (Log on) включить опцию “Разрешить взаимодействие с рабочим столом” (Allow service to interact with desktop).

Start-Service -Name ui0detect

Однако в Windows 10 1803 службу Interactive Services Detection Service полностью убрали из системы, и вы более не можете переключиться в нулевую сессию (Session 0), так что вы просто не увидите окна, которые выводятся из-под аккаунта System.

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

& $NSSMPath set $NewServiceName description “Мониторинг изменений группы AD”

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

Пилим свою службу Windows – руководство для «не настоящих программистов»

Однажды вы задумаетесь, как превратить скрипт или приложение в Windows-службу. Скорее всего, задача окажется не такой уж тривиальной – приложению как минимум потребуется специальный интерфейс для получения команд от системы. А раз есть требования и ограничения, то есть и скрипты, и милые сердцу костылики для преодоления.

Статья будет полезна тем, кто, как и я — «программист не настоящий».

Зачем нужна служба, если есть назначенные задания

В отличие от назначенных заданий служба работает постоянно, запускается при старте ПК и может управляться средствами Windows. А еще регулярно запускаемому скрипту могут понадобиться данные с предыдущего запуска, и может быть полезно получение данных из внешних источников — например, в случае TCP или Web сервера.

Лично мне за последние пять лет приходилось создавать службу три с половиной раза:

  • Потребовалось создать сервис на fail2ban для Windows 2003., который работал с логами FileZilla и Apache, а при подозрении на брутфорс блокировал IP штатными средствами Windows — ipsec.
  • Аналог телнет-сервера для домашних версий Windows. Понадобилось выполнять команды на удаленных рабочих станциях, которые были под управлением Windows 7 Home. По сути, вторая попытка поиграть в службы.
  • Музыкальный проигрыватель для торгового зала под Windows. Задачу по ТЗ можно было решить при помощи mpd и пачки скриптов, но я решил — если уж делать скрипты, то почему бы и не «сваять» проигрыватель самому. За основу взял библиотеку BASS.dll.
  • Когда выбирали веб-сервер с поддержкой загрузки файлов под Windows, одним из вариантов был HFS. Сам по себе работать он не может, поэтому пришлось «запихивать» его в службу. В результате решение не понравилось, и просто установили «тему» Apaxy на web-сервере Apache.
Читать:
Как сделать кнопки в ряд в html

Для создания службы можно использовать взрослые языки программирования вроде C. Но если вы не хотите связываться с Visual Studio, то возьмите готовые утилиты. Существуют платные решения вроде FireDaemon Pro или AlwaysUp, но мы традиционно сосредоточимся на бесплатных.

Способ первый. От Microsoft

Этот уже немолодой механизм состоит из двух компонентов: утилиты instsrv.exe для установки сервиса и srvany.exe — процесса для запуска любых исполняемых файлов. Предположим, что мы создали веб-сервер на PowerShell при помощи модуля Polaris. Скрипт будет предельно прост:


Работа так называемого «сервера».

Теперь попробуем превратить скрипт в службу. Для этого скачаем Windows Resource Kit Tools, где будут наши утилиты. Начнем с того, что установим пустой сервис командой:

Где WebServ — имя нашего нового сервиса. При необходимости через оснастку services.msc можно задать пользователя, под которым будет запускаться служба, и разрешить взаимодействие с рабочим столом.

Теперь пропишем путь к нашему скрипту при помощи магии реестра. Параметры службы есть в разделе реестра HKLM\SYSTEM\CurrentControlSet\Services\WebServ. В нем нам нужно добавить новый раздел Parameters и создать там строковый параметр Application, указав в нем путь к исполняемому файлу. В случае скрипта PowerShell он будет выглядеть так:


Настроенная служба.

Можно запустить и радоваться.


Работающая служба.

Однако у этого способа есть недостатки:

  • Утилиты старые, разработаны до изобретения PowerShell, UAC и прочих вещей.
  • Srvany не контролирует работу приложения. Даже если оно выпадет в ошибку, служба продолжит свое дело как ни в чем не бывало.
  • Придется донастраивать и копаться в реестре. Вы же помните, что копаться в реестре небезопасно?

Поэтому перейдем к методу, частично лишенному этих проблем.

Способ второй, почти взрослый

Существует утилита под названием NSSM — Non-Sucking Service Manager, что можно перевести как не-плохой менеджер служб. В отличие от предыдущей, она поддерживается разработчиком, и исходный код опубликован на сайте. Помимо обычного способа, доступна и установка через пакетный менеджер Chocolately.

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


Установка через PowerShell.

Для разнообразия проверим работу службы не браузером, а тоже через PowerShell командой Invoke-RestMethod.


И вправду работает.

В отличие от srvany, этот метод позволяет перезапускать приложение на старте, перенаправлять stdin и stdout и многое другое. В частности, если не хочется писать команды в командную строку, то достаточно запустить GUI и ввести необходимые параметры через удобный интерфейс.

GUI запускается командой:


Настроить можно даже приоритет и использование ядер процессора.

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

Налицо нехватка «жести». Поэтому я перейду к самому хардкорному методу из всех опробованных.

Способ третий. AutoIT

Поскольку я давний любитель этого скриптового языка, то не смог пройти мимо библиотеки под названием _Services_UDF v4. Она снабжена богатой документацией и примерами, поэтому под спойлером сразу приведу полный текст получившегося скрипта.

Итак, попробуем «завернуть» в нее наш веб-сервис:

Разберу подробнее момент запуска приложения. Он начинается после операции $bServiceRunning = True и превращается в, казалось бы, бесконечный цикл. На самом деле этот процесс прервется, как только служба получит сигнал о завершении — будь то выход из системы или остановка вручную.

Поскольку программа для скрипта является внешней (powershell.exe), то после выхода из цикла нам нужно закончить ее работу с помощью ProcessClose.

Для этого скрипт необходимо скомпилировать в .exe, а затем установить службу, запустив exe с ключом -i.


Оно работает!

Разумеется, этот способ не самый удобный, и все дополнительные возможности придется реализовывать самостоятельно, будь то повторный запуск приложения при сбое или ротация логов. Но зато он дает полный контроль над происходящим. Да и сделать в итоге можно куда больше — от уведомления в Telegram о сбое службы до IPC-взаимодействия с другими программами. И вдобавок — на скриптовом языке, без установки и изучения Visual Studio.

How do I run a PowerShell script as a service?

I created the script below to check my application’s port 2025 and log the number of connections.

I need this script to run as a service on Windows with the name netstat_2025 . Does anyone know if there is such a possibility?

I do not want to use the Task Scheduler, but instead run the script as a service on Windows.

2 Answers 2

You can just download NSSM from nssm.cc them:

Run nssm in command line: nssm install YourServiceName

Set the informations:

  • Path: Powershell path
  • Startup directory: Your script directory
  • Options: .\yourscript.ps1 -arg1 value -arg2 value -arg3 value

enter image description here

Leandro Carvalho's user avatar

My original answer failed to take into account that you still need to implement the service control interfaces, which powershell.exe does not implement. I did look into some other methods of running a PowerShell script as a service, however.

One of the easier tools I came across that does this for you is nssm You can use nssm (Non-Sucking Service Manager) to register a new service and have it run your PowerShell script. You’ll need to make sure your script’s main logic runs within an infinite loop (as most long running programs or services do), and then you can use nssm to register a new service that will run your PowerShell script. Below is an example of putting your code into a main loop that doesn’t terminate:

To register your script as a PowerShell service, you can use the following PowerShell code (note that if you install with Chocolatey , nssm will already be on the PATH , not sure if it is when you manually install):

Похожие статьи