Запуск сценария PowerShell (*.PS1) в качестве службы Windows
Любой сценарий PowerShell можно преобразовать в настоящую службу Windows, которая работает в фоновом режиме и запускается автоматически во время загрузки сервера. Вы можете создать службу Windows с помощью
srvany.exeили
instsrv.exeинструменты (из Windows Server Resource 2003 Kit), которые позволяют запускать
powershell.exeпроцесс с параметром, содержащим путь к файлу сценария PS1.
Основным недостатком создания сервиса этим методом является то, что srvany.exe не контролирует состояние выполнения PowerShell-скрипта, и если приложение выходит из строя (зависает), сервис его не видит и продолжает работать. Для создания службы Windows из файла, содержащего сценарий PowerShell, в этой статье мы будем использовать набор инструментов NSSM (Non-Suck Service Manager), который не демонстрирует вышеупомянутых недостатков.
Вы можете загрузить и установить NSSM вручную или с помощью Chocolatey. Во-первых, установите сам Choco:
Set-ExecutionPolicy Bypass -Scope Process -Force; `
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))Затем установите пакет NSSM:
choco install nssmВ этом примере мы будем отслеживать изменения в конкретной группе Active Directory в режиме реального времени и информировать администратора безопасности с помощью всплывающего уведомления и электронной почты (скрипт приведен в этой статье).
Итак, у нас есть код PowerShell, который необходимо сохранить в виде файла PS1. Добавим бесконечный цикл, выполняющий проверку каждую минуту:
while($true) {
#Your PS code
Start-Sleep -Seconds 60
}Конечно, для реализации такого сценария можно создать отдельную задачу в Планировщике заданий. Но если вам приходится реагировать на изменения в режиме реального времени, лучше использовать метод отдельного обслуживания.
Вы можете создать службу из сценария PowerShell, используя NSSM непосредственно из 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Запустите новый сервис:
Start-Service $NewServiceNameПроверьте статус службы в PowerShell:
Get-Service $NewServiceNameИтак, вы создали и запустили новую службу Windows. Убедитесь, что он появился в консоли управления службами (services.msc).
CheckADGroup появился, он настроен на автоматический запуск и в данный момент работает. Как видите, ваш сценарий PowerShell выполняется внутри процесса nssm.exe.
Обратите внимание, что служба работает под учетной записью System. Если вы используете другие модули в своих сценариях PowerShell (в моем случае Get-ADGroupMember из Active Directory для Windows PowerShell используется для получения списка участников группы безопасности домена), эта учетная запись должна иметь доступ к файлам модуля PS и AD. разрешения на подключение (в моем случае). Вы также можете запустить эту службу под другой учетной записью домена (или учетной записью gMSA) и разрешить пользователям останавливать/перезапускать службу, если у них нет прав локального администратора.
Чтобы служба могла отображать уведомления во время сеанса пользователя, включите параметр Разрешить службе взаимодействовать с рабочим столом на вкладке Вход.
Чтобы он работал в Windows 10 и Windows Server 2012 R2/2016, измените значение параметра DWORD NoInteractiveServices в разделе реестра HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Windows на 0. и запустите Службу обнаружения интерактивных служб:
Start-Service -Name ui0detectОднако служба обнаружения интерактивных служб была полностью удалена из Windows 10, сборка 1803, и вы не сможете переключиться на сеанс 0. Поэтому вы не увидите окна уведомлений, отображаемые под системной учетной записью.
Изменить описание сервиса можно с помощью этой команды:
& $NSSMPath set $NewServiceName description “Monitoring of AD group changes”Чтобы удалить созданный вами сервис, используйте команду
sc deleteкоманда или:
nssm remove CheckADGroup


