如何检测Windows服务器在重启后是否可用?

5
我想使用任务计划程序或类似工具自动化Windows 2000+服务器重启过程,以远程重启服务器并等待其重新启动。我可以使用“shutdown”或“psshutdown”进行远程重启,但我需要比“sleep”更好的方法来等待其重新启动。我需要在“n”分钟内验证它是否已经重新上线,如果没有,则抛出错误。
关于“重新上线”,我想验证的不仅仅是可以ping通,而是RFC服务是否响应或其他确定的重要信息。
我更喜欢NT脚本方法,但我不排除编写自定义工具来完成此操作。
有什么想法吗?
7个回答

8

在研究了一段时间后,我想出了以下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

不错!我测试了一下,它的表现和广告描述的一样。你需要使用一个具有远程服务器管理员权限的帐户来运行;如果能提供这样的凭据就更好了。 - quux
您可以使用“runas”封装此命令以提供替代凭据。 - spoulson

2

你可以使用psservice来查询RFC或打印池服务的状态。打印池通常是最后启动的服务之一。你可以使用以下语法:

psservice \\someothermachine query spooler

一旦服务正在运行,它将返回如下内容:
SERVICE_NAME: Spooler                                                                             
DISPLAY_NAME: 打印池                                                                              
管理所有本地和网络打印队列,并控制所有打印作业。如果此服务停止,则本地计算机上的打印将不可用。如果禁用此服务,则任何明确依赖于它的服务都将无法启动。                                      
        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                                                                   
如果另一台计算机没有准备好,您将收到以下内容:
无法连接到 \\someothermachine:                                                                  
RPC 服务器不可用。

2
你的远程重启脚本可以启动服务器,等待n分钟,然后查询你的RFC服务。你也可以在服务器上有一个本地脚本完成相同的操作。

1

0
您可以轮询一些核心服务,以查看它是否已启动:
sc "\\server_name" query EventSystem

0
使用nmap获取机器上开放服务的列表,并解析结果以确保您需要的服务处于活动状态。还有一个有用的技巧是确保您不需要的服务处于非活动状态。

0
关键在于我需要编写脚本。从 psservice/sc query 中提取服务状态的更好方法是什么?我可以将其导入到 findstr "RUNNING",但肯定有更好的方法。

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