5

我想使用任务计划程序或类似工具自动执行 Windows 2000+ 服务器重新启动过程,以远程重新启动服务器并等待它重新启动。我可以发出shutdownpsshutdown远程重启,但我想要的东西比sleep等待它回来更好。我需要在n几分钟内验证它是否重新上线或抛出错误。

通过“重新上线”,我想验证的不仅仅是它可以被 ping 通,还可能是它的 RFC 服务正在响应或其他一些确定的生命体征。

我更喜欢 NT 脚本方法,但我不排除编写自定义工具来执行此操作。

有任何想法吗?

4

7 回答 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
于 2008-09-29T12:11:41.023 回答
2

您的远程重启脚本可以启动服务器,等待 n 分钟,然后查询您的 RFC 服务。您也可以让服务器上的本地脚本执行相同的操作。

于 2008-09-11T14:18:16.613 回答
2

您可以使用psservice来查询 RFC 或 Print Spooler 服务的状态。后台处理程序通常是最后启动的服务之一。您可以使用如下语法:

psservice \\someothermachine query spooler

一旦服务运行,这将返回类似的内容。

SERVICE_NAME:后台处理程序                                                                             
DISPLAY_NAME:打印后台处理程序                                                                       
管理所有本地和网络打印队列并控制所有打印作业。如果此服务停止
ped,本地机器上的打印将不可用。如果此服务被禁用,任何服务
明确依赖它的将无法启动。                                                  
        组 : 后台处理程序组                                                          
        类型:110 WIN32_OWN_PROCESS INTERACTIVE_PROCESS                             
        状态 : 4 正在运行                                                            
                               (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)                          
        WIN32_EXIT_CODE:0 (0x0)                                                              
        SERVICE_EXIT_CODE:0 (0x0)                                                              
        检查点:0x0                                                                   
        等待提示:0x0                                                                   

如果另一台机器还没有准备好,你会得到类似的东西

无法连接到 \\someothermachine:                                                                  
RPC 服务器不可用。
于 2008-09-11T14:21:57.917 回答
1

使用 VBScript (WSH),您可以使用 .state 属性对其进行检查。此脚本显示该属性在不同的应用程序中使用,但应该有助于说明这个想法:

http://www.robvanderwoude.com/vbstech_proc_service.html

于 2008-09-11T15:37:08.827 回答
0

您可以轮询一些核心服务以查看它是否已启动:

sc "\\server_name" query EventSystem
于 2008-09-11T14:23:50.877 回答
0

使用nmap获取机器上开放服务的列表并解析结果以确保您需要的服务处于活动状态。确保您不需要的东西处于活动状态也很有用。

于 2008-09-11T14:24:57.037 回答
0

这里的关键是我需要编写脚本。有没有更简洁的方法从psservice/中提取服务状态sc query?我可以将它通过管道传输到findstr "RUNNING",但必须有更好的方法。

于 2008-09-11T14:41:11.583 回答