З будь-якого скрипта 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. Спочатку потрібно встановити сам 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
Запустимо нову службу:
Start-Service $ NewServiceName
Перевіримо статус служби за допомогою PowerShell:
Get-Service $ NewServiceName
Отже, ви створили і запустили нову службу Windows. Перевіримо, що вона з'явилася в консолі управління службами services.msc
Служба CheckADGroupSrv дійсно з'явилася, вона налаштована на автоматичний запус і в даний момент запущена (Running). Як ви бачите, ваш PowerShell скрипт запущений всередині процесу nssm.exe.
Зверніть увагу, що служба запущена з-під облікового запису System. Якщо ви використовуєте в своїх PS скриптах інші модулі (в моєму випадку для отримання складу доменної групи безпеки використовується командлет Get-ADGroupMember з модуля Active Directory для Windows PowerShell), цей акаунт повинен мати доступ до файлів модуля і права на підключення до AD (в моєму випадку). Ви так само можете запустити цю служби під інший обліковим записом (або аккаунтом gMSA) і надати користувачам права на зупинку / перезапуск служби, якщо у них немає прав локального адміністратора.Щоб служба могла відображати повідомлення в сеанс користувача (взаємодіяти з робочим столом) потрібно на вкладці "Вхід у систему"(Log on) включити опцію"Дозволити взаємодію з робочим столом"(Allow service to interact with desktop).
Щоб це працювало в Windows 10 / Windows Server 2012 R2 / 2016 потрібно змінити значення DWORD параметра реєстру NoInteractiveServices в гілці HKLM \ System \ CurrentControlSet \ Control \ Windows на 0 і включити службу оглядача інтерактивних служб (Interactive Services Detection Service):Start-Service -Name ui0detect
Однак в Windows 10 1803 службу Interactive Services Detection Service повністю прибрали з системи, і ви більше не можете переключитися в нульову сесію (Session 0), так що ви просто не побачите вікна, які виводяться з-під аккаунта System.
Ви можете змінити опис служби командою:
& $ NSSMPath set $ NewServiceName description "Моніторинг змін групи AD"
Щоб видалити створену службу можете скористатися командою sc delete або
nssm remove CheckADGroupSrv