我正在尝试编写更强大的Stop-Service cmdlet(PSv3)。基本上,通过使用一个调用Stop-Service的函数,然后测试服务状态,以查看服务是否真的停止并最终升级为服务的进程终止。
我试图编写或找到一个不会优雅停止的服务,但在收到停止通知后往往会留下来。
我的不好'服务只是使用这个:
protected override void OnStop()
{
TheEventLog.WriteEntry("StrongBad in OnStop");
Thread.Sleep(300000);
}
但是服务确实在停止服务允许的任何超时内停止。
PS C:\WINDOWS\system32> Stop-Service -Name StrongBad
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
WARNING: Waiting for service 'Trogdor (StrongBad)' to stop...
PS C:\WINDOWS\system32> Get-Service StrongBad
Status Name DisplayName
------ ---- -----------
Stopped StrongBad Trogdor
我真的希望(在这种情况下需要)Stop-Service cmdlet返回一条消息,说明服务未能在指定的时间内停止。
当服务具有依赖关系时,似乎我看到类似于预期的行为:
PS C:\src\Enterprise\Enterprise\Systems\Scripts\Powershell\Includes> Stop-Service -Name nsi -Force
Stop-Service : Service 'Network Store Interface Service (nsi)' cannot be stopped due to the following error: Cannot stop LanmanWorkstation service on computer '.'.
At line:1 char:1
+ Stop-Service -Name nsi -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : CloseError: (System.ServiceProcess.ServiceController:ServiceController) [Stop-Service], ServiceCommandException
+ FullyQualifiedErrorId : CouldNotStopService,Microsoft.PowerShell.Commands.StopServiceCommand
Stop-Service : Collection was modified; enumeration operation may not execute.
At line:1 char:1
+ Stop-Service -Name nsi -Force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Stop-Service], InvalidOperationException
+ FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.StopServiceCommand
答案 0 :(得分:1)
无法让Stop-Service
超时。很高兴等待服务停止(问我怎么知道)。根据{{3}},您需要启动后台作业来停止服务,等待它完成,如果服务没有停止,请将其删除:
Start-Job { Stop-Service StrongBad } | Wait-Job -Timeout 30
$svc = Get-Service StrongBad
if( $svc.Status -ne 'Stopped' )
{
# This assumes the process name is strongbad
Stop-Process StrongBad
}
答案 1 :(得分:0)
这真的是一个两部分问题。第一部分是如何编写一个不会立即关闭的服务,以便我可以测试更强大的停止服务。
这一半问题的答案是我需要在停止时在服务中设置WaitHint:
serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
问题的后半部分我如何使停止服务更加强大是@Aaron所说的,但我更多地将其概括为:
$sb = [scriptblock]::Create("Stop-Service $ServiceName")
$jobid = Start-Job $sb | Wait-Job -Timeout $Timeout