如何在重新启动后检测 Windows 服务器是否可用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/56644/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I detect if a Windows server is available after a reboot?
提问by spoulson
I want to automate a Windows 2000+ server reboot process using Task Scheduler or similar tool to remotely reboot a server and wait for it to come back up. I can issue shutdown
or psshutdown
to remotely reboot, but I want something better than sleep
to wait for it to come back. I need to verify it is back online within n
minutes or throw an error.
我想使用任务计划程序或类似工具自动执行 Windows 2000+ 服务器重新启动过程,以远程重新启动服务器并等待它重新启动。我可以发出shutdown
或psshutdown
远程重启,但我想要比sleep
等待它回来更好的东西。我需要在n
几分钟内验证它是否重新联机或引发错误。
By 'back online', I would like to verify more than just that it can be pinged, but perhaps its RFC service is responding or some other determinate vital sign.
通过“重新上线”,我想验证的不仅仅是它可以被 ping,而且它的 RFC 服务可能正在响应或其他一些确定的生命体征。
I'd prefer an NT script approach, but I'm not ruling out writing a custom tool to do this.
我更喜欢 NT 脚本方法,但我不排除编写自定义工具来执行此操作。
Any ideas?
有任何想法吗?
采纳答案by Bill the Lizard
Your remote restart script could start the server, wait n minutes, then query your RFC service. You could also have a local script on the server do the same thing.
您的远程重启脚本可以启动服务器,等待 n 分钟,然后查询您的 RFC 服务。您也可以让服务器上的本地脚本做同样的事情。
回答by spoulson
After working on this for a while, I came up with the following VBScript. Feel free to comment/improve.
在研究了一段时间之后,我想出了以下 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
回答by Chris Miller
You could use psserviceto query the status of the RFC or Print Spooler services. The Spooler is usually one of the last services to start. You could use syntax like:
您可以使用psservice查询 RFC 或 Print Spooler 服务的状态。后台处理程序通常是最后启动的服务之一。您可以使用以下语法:
psservice \someothermachine query spooler
That will return something like this once the service is running.
一旦服务运行,这将返回类似的内容。
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
If the other machine is not ready, you'll get something like
如果另一台机器没有准备好,你会得到类似的东西
Unable to connect to \someothermachine: The RPC server is unavailable.
回答by busse
With VBScript (WSH) you could check it with the .state property. This script shows that property being used in a different application but should help illustrate the idea:
使用 VBScript (WSH),您可以使用 .state 属性检查它。此脚本显示该属性在不同的应用程序中使用,但应该有助于说明这个想法:
回答by JosephStyons
You can poll some core service to see if it has started:
您可以轮询一些核心服务以查看它是否已启动:
sc "\server_name" query EventSystem
回答by Joel Coehoorn
回答by spoulson
The key here is I need to script this. Is there a cleaner way to extract the service status from psservice
/sc query
? I'm able to pipe it to findstr "RUNNING"
, but there's got to be a better way.
这里的关键是我需要编写脚本。有没有更简洁的方法可以从psservice
/ 中提取服务状态sc query
?我可以通过管道将它传输到findstr "RUNNING"
,但必须有更好的方法。