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





Сценарий удаленного перезапуска может запустить сервер, подождать n минут, а затем запросить службу RFC. У вас также может быть локальный сценарий на сервере, выполняющий то же самое.
Вы можете использовать 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.
Вы можете опросить базовую службу, чтобы узнать, запущена ли она:
sc "\server_name" query EventSystem
Используйте nmap, чтобы получить список открытых служб на машине и проанализировать результаты, чтобы убедиться, что то, что вам нужно, активно. Также полезно убедиться, что вещи, которые вам нужны не, активны.
Ключевым моментом здесь является то, что мне нужно это написать. Есть ли более чистый способ извлечь статус службы из psservice / sc query? Я могу подключить его к findstr "RUNNING", но должен быть способ получше.
С помощью VBScript (WSH) вы можете проверить это с помощью свойства .state. Этот сценарий показывает, что это свойство используется в другом приложении, но должен помочь проиллюстрировать идею:
Поработав над этим некоторое время, я придумал следующий сценарий 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
Вы можете заключить эту команду в «runas», чтобы предоставить альтернативные учетные данные.
Отлично! Я проверил это, и он работает как рекламируется. Вам необходимо работать с учетной записью с правами администратора на удаленном сервере; возможность предоставить такие кредиты была бы изящной.