作为Windows服务运行PowerShell脚本(*。PS1)

时间:2020-01-09 10:46:52  来源:igfitidea点击:

任何PowerShell脚本都可以转换为真正的Windows服务,该服务在后台运行并在服务器启动期间自动启动。我们可以使用以下方法创建Windows服务

srvany.exe

或者

instsrv.exe

工具(来自Windows Server Resource 2003 Kit),可让我们运行

powershell.exe

使用包含PS1脚本文件路径的参数进行处理。

使用此方法创建服务的主要缺点是srvany.exe不能控制PowerShell脚本的执行状态,并且如果应用程序崩溃(挂起),该服务将看不到它并继续运行。为了从包含PowerShell脚本的文件中创建Windows服务,在本文中,我们将使用NSSM(非吸吮服务管理器)工具包,该工具包不会演示上述缺点。

我们可以手动下载或者安装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进程中运行。

请注意,该服务正在系统帐户下运行。如果我们在PowerShell脚本中使用其他模块(在我的情况下,则使用Active Directory for Windows PowerShell的Get-ADGroupMember获取域安全组中的成员列表),此帐户必须有权访问PS模块文件和AD连接权限(以我为例)。我们还可以在另一个域帐户(或者gMSA帐户)下启动此服务,并允许用户在没有本地管理员权限的情况下停止/重新启动该服务。

为了使服务可以在用户会话中显示通知,请在"登录"选项卡上启用"允许服务与桌面交互"选项。

为了使其能够在Windows 10和Windows Server 2012 R2/2015中工作,请将注册表项HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Windows中的DWORDNoInteractiveServices参数值更改为0并运行Interactive Services Detection Service

Start-Service -Name ui0detect

但是,Interactive Services Detection服务已从Windows 10内部版本1803中完全删除,我们将无法切换到会话0。因此,我们将不会看到系统帐户下显示的通知窗口。

我们可以使用以下命令更改服务描述:

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

要删除我们创建的服务,请使用

sc delete

命令或者:

nssm remove CheckADGroup