Как определить, доступен ли сервер Windows после перезагрузки? - PullRequest
5 голосов
/ 11 сентября 2008

Я хочу автоматизировать процесс перезагрузки сервера Windows 2000+ с помощью планировщика заданий или аналогичного инструмента для удаленной перезагрузки сервера и ожидания его восстановления. Я могу выдать shutdown или psshutdown для удаленной перезагрузки, но я хочу что-то лучше, чем sleep, чтобы дождаться его возвращения. Мне нужно убедиться, что он снова в сети через n минуты или выдать ошибку.

«Вернувшись в оперативный режим», я хотел бы проверить не только то, что он может быть проверен, но, возможно, его служба RFC отвечает или какой-то другой определенный жизненный знак.

Я бы предпочел подход со сценарием NT, но я не исключаю написание специального инструмента для этого.

Есть идеи?

Ответы [ 7 ]

8 голосов
/ 29 сентября 2008

Поработав некоторое время, я разработал следующий 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
2 голосов
/ 11 сентября 2008

Вы можете использовать psservice для запроса статуса RFC или сервисов очереди печати. Спулер обычно является одним из последних сервисов для запуска. Вы можете использовать синтаксис, такой как:

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. 
2 голосов
/ 11 сентября 2008

Ваш скрипт удаленного перезапуска может запустить сервер, подождать n минут и запросить службу RFC. Вы также можете сделать так, чтобы локальный скрипт на сервере делал то же самое.

1 голос
/ 11 сентября 2008

С помощью VBScript (WSH) вы можете проверить это с помощью свойства .state. Этот скрипт показывает, что свойство используется в другом приложении, но должно помочь проиллюстрировать идею:

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

0 голосов
/ 11 сентября 2008

Ключ в том, что мне нужно написать скрипт. Есть ли более чистый способ извлечь статус услуги из psservice / sc query? Я могу передать это на findstr "RUNNING", но должен быть лучший способ.

0 голосов
/ 11 сентября 2008

Используйте nmap , чтобы получить список открытых служб на машине и проанализировать результаты, чтобы убедиться, что то, что вам нужно, активно. Также полезно убедиться, что вещи, которые вам не нужны, не активны.

0 голосов
/ 11 сентября 2008

Вы можете опросить некоторую базовую службу, чтобы узнать, запущена ли она:

sc "\\server_name" query EventSystem
...