如何将PowerShell脚本作为服务运行?

6

我创建了下面的脚本来检查我的应用程序的2025端口并记录连接数。

我需要将此脚本作为Windows服务运行,服务名称为netstat_2025。 有人知道是否存在这样的可能性吗?

我不想使用任务计划程序,而是在Windows上将脚本作为服务运行。

脚本SCTT521CTO.ps1

$startTime =  (Get-Date).ToString("dd_MM_yyyy")
$LogDate = ((get-date).ToLocalTime()).ToString("yyyy-MM-ddTHH:mm:ss.fff")
$hostname = hostname

$portTServer = 8000
$FileTserver = netstat -ano | findstr "8000"

$LogTserver = $LogDate + " - Quantidade de Conexoes na porta " + $portTServer + ": " + $FileTserver.count + " - Servidor: " + $hostname
$LogTserver | Out-File -Append D:\SCTT521CTO\netstat_$startTime.log

$limit = (Get-Date).AddDays(-5)
$path = "D:\SCTT521CTO\*"
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

运行服务脚本:service.ps1

# Desired name of the service
$serviceName = 'netstat_2025'

# Get the full path to powershell.exe
$powershellPath = ( Get-Command powershell ).Source

# The path to the script you want to run as a service
$serviceScriptPath = D:\scripts\SCTT521CTO.ps1

# The arguments to pass to the powershell executable each time the service starts
$args = '-ExecutionPolicy Bypass -NoProfile -File "{0}"' -f $serviceScriptPath

# Install the service using nssm
nssm install $serviceName $powershellPath $args

# See that the service is registered and check its status
Get-Service $serviceName

我按照示例操作了,但不起作用。服务已创建,但无法启动。 - Leandro de Matos
sc.exe create PS_Trigger_Service Displayname= "PS_Trigger_Service" binpath= "D:\SCRIPTS\SCTT521CTO.ps1" start= auto - Leandro de Matos
尝试启动服务时返回错误。 “错误193:0Xc1” - Leandro de Matos
@LeandrodeMatos 请查看我的更新答案。 - codewario
显示剩余7条评论
2个回答

4
你可以从nssm.cc下载NSSM:

  1. 在命令行中运行nssm:nssm install YourServiceName

  2. 设置信息:

  • 路径:Powershell路径
  • 启动目录:你的脚本目录
  • 选项:.\yourscript.ps1 -arg1 value -arg2 value -arg3 value

enter image description here

就这样。


2
我的原始回答没有考虑到您仍然需要实现服务控制接口,而powershell.exe没有实现。我确实研究了一些其他运行PowerShell脚本作为服务的方法。
我遇到的其中一个更容易使用的工具是nssm。您可以使用nssm(非吸管服务管理器)来注册新服务并运行您的PowerShell脚本。您需要确保脚本的主要逻辑在一个无限循环中运行(大多数长时间运行的程序或服务都是如此),然后您可以使用nssm来注册一个新服务来运行您的PowerShell脚本。以下是将您的代码放入不终止的主循环的示例:
while( $true ) {
  $startTime =  (Get-Date).ToString("dd_MM_yyyy")
  $LogDate = ((get-date).ToLocalTime()).ToString("yyyy-MM-ddTHH:mm:ss.fff")
  $hostname = hostname

  $portTServer = 8000
  $FileTserver = netstat -ano | findstr "8000"

  $LogTserver = $LogDate + " - Quantidade de Conexoes na porta " + $portTServer + ": " + $FileTserver.count + " - Servidor: " + $hostname
  $LogTserver | Out-File -Append D:\SCTT521CTO\netstat_$startTime.log

  $limit = (Get-Date).AddDays(-5)
  $path = "D:\SCTT521CTO\*"
  Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force

  # Add a sleep at the end of the loop to prevent the script from eating
  # too much CPU time
  Start-Sleep -Seconds 60
}

要将您的脚本注册为PowerShell服务,可以使用以下PowerShell代码(请注意,如果您使用Chocolatey安装,则nssm已经在PATH上,如果您手动安装,则不确定是否存在):

# Desired name of the service
$serviceName = 'netstat_2025'

# Get the full path to powershell.exe
$powershellPath = ( Get-Command powershell ).Source

# The path to the script you want to run as a service
$serviceScriptPath = C:\path\to\service\script.ps1

# The arguments to pass to the powershell executable each time the service starts
$args = '-ExecutionPolicy Bypass -NoProfile -File "{0}"' -f $serviceScriptPath

# Install the service using nssm
nssm install $serviceName $powershellPath $args

# See that the service is registered and check its status
Get-Service $serviceName

您的服务现在应该已经安装并可以像任何其他Windows服务一样进行控制。其工作原理是,它不会直接将powershell.exe注册为服务,而是将nssm.exe注册为服务可执行文件,实现了正确的服务控制处理程序,然后运行您为此服务配置的任何程序(在本例中,使用powershell.exe调用您的脚本)。


你好,我创建了一个服务,但是尝试启动它时返回以下错误:“服务没有及时响应启动请求或控制。”到目前为止,我尝试过的一个解决方案是在Windows注册表中创建一个名为ServicesPipeTimeout的键,希望错误是由于启动服务的等待时间太短,但不幸的是它并没有解决问题。我该怎么办?我应该改变我的代码吗? - Leandro de Matos
1
当然,主要问题在于服务是特殊的可执行文件,它们响应控制信号,而powershell.exe并不是设计为服务。OP应该选择使用计划任务来运行脚本。 - Bill_Stewart
@BendertheGreatest,我尝试了一些方法,但无法更新代码,你能告诉我该怎么做吗? - Leandro de Matos
2
您不能直接将PowerShell脚本运行为服务,因为powershell.exe不是一个服务可执行文件。调度程序中的所有任务如何自动删除?任务计划程序是核心操作系统组件。解决该问题并作为任务运行,或使用其他工具来安排程序运行。 - Bill_Stewart
1
然而,有些情况下,长时间运行的服务比定时任务更可取。解决这个问题仍然是值得了解的。我正在更新我的答案,介绍如何使用PowerShell正确实现此功能。 - codewario
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接