重新启动后如何检测Windows服务器是否可用?
时间:2020-03-05 18:51:28 来源:igfitidea点击:
我想使用任务计划程序或者类似工具自动执行Windows 2000+服务器的重新引导过程,以远程重新引导服务器并等待其重新启动。我可以发出shutdown
或者psshutdown
来远程重启,但是我想要比sleep
更好的东西来等待它回来。我需要在n分钟内确认它已重新联机,否则会引发错误。
通过"重新联机",我不仅要验证它是否可以被ping通,还可以验证它的RFC服务是否正在响应或者其他确定的生命体征。
我更喜欢NT脚本方法,但是我不排除编写自定义工具来执行此操作的可能性。
有任何想法吗?
解决方案
回答
远程重启脚本可以启动服务器,等待n分钟,然后查询RFC服务。我们还可以在服务器上让本地脚本执行相同的操作。
回答
我们可以使用psservice查询RFC或者Print Spooler服务的状态。后台打印程序通常是启动的最后一项服务。我们可以使用如下语法:
psservice \someothermachine query spooler
服务运行后,将返回类似的内容。
SERVICE_NAME: Spooler DISPLAY_NAME: Print Spooler Manages all local and network print queues and controls all printing jobs. If this service is stop ped, printing on the local machine will be unavailable. If this service is disabled, any services that explicitly depend on it will fail to start. GROUP : SpoolerGroup TYPE : 110 WIN32_OWN_PROCESS INTERACTIVE_PROCESS STATE : 4 RUNNING (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0
如果另一台机器没有准备好,我们将得到类似
Unable to connect to \someothermachine: The RPC server is unavailable.
回答
我们可以轮询一些核心服务以查看其是否已启动:
sc "\server_name" query EventSystem
回答
使用nmap获取计算机上打开的服务的列表,并解析结果以确保我们所需要的处于活动状态。确保不需要的东西不活动也很有用。
回答
这里的关键是我需要编写脚本。有没有一种更清洁的方法可以从psservice / sc query中提取服务状态?我可以将其传递给findstr" RUNNING"
,但是必须有一个更好的方法。
回答
使用VBScript(WSH),我们可以使用.state属性进行检查。该脚本显示了该属性正在其他应用程序中使用,但应有助于说明这一点:
http://www.robvanderwoude.com/vbstech_proc_service.html
回答
经过一段时间的研究之后,我想到了以下VBScript。随时发表评论/改进。
' ' Remotely reboot a server and ' wait for server to come back up. ' ' Usage: cscript /nologo /E:VBScript RebootWait.vbs <Server Name> ' ' Shawn Poulson, 2008.09.11 ' ' ' Get server name from command line ' If WScript.Arguments.Count <> 1 Then ShowUsage() WScript.Quit(1) End If ServerName = WScript.Arguments(0) ' ' Verify server is currently up ' WScript.StdOut.WriteLine Now & ": Verify server '" & ServerName & "' is currently up..." If Not IsAvailable(ServerName) Then WScript.StdOut.WriteLine "Error: Server is down. Reboot aborted!" WScript.Quit(1) End If WScript.StdOut.WriteLine Now & ": Server is up." ' ' Reboot server ' WScript.StdOut.WriteLine Now & ": Rebooting server '" & ServerName & "'..." RebootStatus = RebootServer(ServerName) If RebootStatus < 0 Then WScript.StdOut.WriteLine "Error: Reboot returned error " & RebootStatus WScript.Quit(1) End If WScript.StdOut.WriteLine Now & ": Reboot command was successful" ' ' Wait for server to come down ' WScript.StdOut.Write Now & ": Waiting for server '" & ServerName & "' to go down..." WaitCount = 0 Do While IsAvailable(ServerName) WaitCount = WaitCount + 1 If WaitCount > 60 Then ' 5 min timeout WScript.StdOut.WriteLine "Error: Timeout waiting for server to come down!" WScript.Quit(1) End If WScript.StdOut.Write(".") WScript.Sleep(5000) Loop WScript.StdOut.WriteLine "Success!" WScript.StdOut.WriteLine Now & ": Server is down." ' ' Wait for server to come back up ' WScript.StdOut.Write Now & ": Waiting for server '" & ServerName & "' to come back up..." WaitCount = 0 Do While Not IsAvailable(ServerName) WaitCount = WaitCount + 1 If WaitCount > 240 Then ' 20 min timeout WScript.StdOut.WriteLine "Error: Timeout waiting for server to come back up!" WScript.Quit(1) End If WScript.StdOut.Write(".") WScript.Sleep(5000) Loop WScript.StdOut.WriteLine "Success!" WScript.StdOut.WriteLine Now & ": Server is back up after reboot." ' ' Success! ' WScript.Quit(0) Sub ShowUsage() WScript.Echo "Usage: " & WScript.ScriptName & " <Server name>" End Sub ' Returns: ' 1 = Successfully issued reboot command ' -2 = Could not reach server ' -3 = Reboot command failed Function RebootServer(ServerName) Dim OpSystem On Error Resume Next For Each OpSystem in GetObject("winmgmts:{(Shutdown)}!\" & ServerName & "\root\CIMV2").ExecQuery("select * from Win32_OperatingSystem where Primary=true") On Error GoTo 0 If IsObject(OpSystem) Then ' Invoke forced reboot If OpSystem.Win32Shutdown(6, 0) = 0 Then ' Success RebootServer = 1 Else ' Command failed RebootServer = -3 End If Else RebootServer = -2 End If Next End Function ' Return True if available Function IsAvailable(ServerName) ' Use Windows RPC service state as vital sign IsAvailable = (GetServiceState(ServerName, "RpcSs") = "Running") End Function ' Return one of: ' Stopped, Start Pending, Stop Pending, ' Running, Continue Pending, Pause Pending, ' Paused, Unknown Function GetServiceState(ServerName, ServiceName) Dim Service On Error Resume Next Set Service = GetObject("winmgmts:\" & ServerName & "\root\CIMV2:Win32_Service='" & ServiceName & "'") On Error GoTo 0 If IsObject(Service) Then GetServiceState = Service.State End Function