关于sysadmin:重新启动后如何检测Windows服务器是否可用?

关于sysadmin:重新启动后如何检测Windows服务器是否可用?

How do I detect if a Windows server is available after a reboot?

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

通过"重新联机",我不仅要验证它是否可以被ping通,还可以验证它的RFC服务是否正在响应或其他确定的生命体征。

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

有任何想法吗?


经过一段时间的研究后,我想到了以下VBScript。随时发表评论/改进。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'
' 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 &"\
oot\\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 &"\
oot\\CIMV2:Win32_Service='" & ServiceName &"'")
   On Error GoTo 0
   If IsObject(Service) Then GetServiceState = Service.State
End Function

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

1
psservice \\\\someothermachine query spooler

服务运行后,将返回类似的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
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

如果另一台机器尚未准备就绪,您将得到类似

1
2
Unable to connect to \\\\someothermachine:                                                                  
The RPC server is unavailable.

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


使用VBScript(WSH),可以使用.state属性进行检查。该脚本显示了该属性正在其他应用程序中使用,但应有助于说明这一点:

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


这里的关键是我需要编写脚本。有没有一种更干净的方法可以从psservice / sc query中提取服务状态?我可以将其传送到findstr"RUNNING",但是必须有一种更好的方法。


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


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

1
sc"\\\\server_name" query EventSystem


推荐阅读