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

发布于 2024-07-05 04:45:52 字数 344 浏览 11 评论 0原文

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

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

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

有任何想法吗?

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.

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.

I'd prefer an NT script approach, but I'm not ruling out writing a custom tool to do this.

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

泪眸﹌ 2024-07-12 04:45:52

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

After working on this for a while, I came up with the following VBScript. Feel free to comment/improve.

'
' 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
月光色 2024-07-12 04:45:52

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

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.

生活了然无味 2024-07-12 04:45:52

您可以使用 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. 

You could use psservice to 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 \\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. 
嘴硬脾气大 2024-07-12 04:45:52

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

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

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:

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

酒解孤独 2024-07-12 04:45:52

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

Use nmap to get a list of open services on the machine and parse the results to make sure what you need is active. It's also useful to make sure that things you don't need are not active.

风透绣罗衣 2024-07-12 04:45:52

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

sc "\\server_name" query EventSystem

You can poll some core service to see if it has started:

sc "\\server_name" query EventSystem
迷鸟归林 2024-07-12 04:45:52

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文