<p>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 <code>shutdown</code> or <code>psshutdown</code> to remotely reboot, but I want something better than <code>sleep</code> to wait for it to come back.  I need to verify it is back online within <code>n</code> minutes or throw an error.</p>

<p>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.</p>

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

<p>Any ideas?</p>

[{'answer_id': 56650, 'author': 'Bill the Lizard', 'author_id': 1288, 'author_profile': 'https://Stackoverflow.com/users/1288', 'pm_score': 3, 'selected': True, 'text': '<p>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.</p>\n'}, {'answer_id': 56660, 'author': 'Chris Miller', 'author_id': 206, 'author_profile': 'https://Stackoverflow.com/users/206', 'pm_score': 2, 'selected': False, 'text': '<p>You could use <a href="http://technet.microsoft.com/en-us/sysinternals/default.aspx" rel="nofollow noreferrer">psservice</a> 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:</p>\n\n<pre><code>psservice \\\\someothermachine query spooler\n</code></pre>\n\n<p>That will return something like this once the service is running.</p>\n\n<pre>\nSERVICE_NAME: Spooler                                                                             \nDISPLAY_NAME: Print Spooler                                                                       \nManages all local and network print queues and controls all printing jobs. If this service is stop\nped, printing on the local machine will be unavailable. If this service is disabled, any services \nthat explicitly depend on it will fail to start.                                                  \n        GROUP             : SpoolerGroup                                                          \n        TYPE              : 110 WIN32_OWN_PROCESS INTERACTIVE_PROCESS                             \n        STATE             : 4  RUNNING                                                            \n                               (STOPPABLE,NOT_PAUSABLE,ACCEPTS_SHUTDOWN)                          \n        WIN32_EXIT_CODE   : 0  (0x0)                                                              \n        SERVICE_EXIT_CODE : 0  (0x0)                                                              \n        CHECKPOINT        : 0x0                                                                   \n        WAIT_HINT         : 0x0                                                                   </pre>\n\n<p>If the other machine is not ready, you\'ll get something like</p>\n\n<pre>Unable to connect to \\\\someothermachine:                                                                  \nThe RPC server is unavailable. </pre>                                                                   \n'}, {'answer_id': 56666, 'author': 'JosephStyons', 'author_id': 672, 'author_profile': 'https://Stackoverflow.com/users/672', 'pm_score': 0, 'selected': False, 'text': '<p>You can poll some core service to see if it has started:</p>\n\n<pre><code>sc "\\\\server_name" query EventSystem\n</code></pre>\n'}, {'answer_id': 56669, 'author': 'Joel Coehoorn', 'author_id': 3043, 'author_profile': 'https://Stackoverflow.com/users/3043', 'pm_score': 0, 'selected': False, 'text': '<p>Use <a href="http://nmap.org/download.html" rel="nofollow noreferrer">nmap</a> 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 <em>don\'t</em> need are <em>not</em> active.</p>\n'}, {'answer_id': 56719, 'author': 'spoulson', 'author_id': 3347, 'author_profile': 'https://Stackoverflow.com/users/3347', 'pm_score': 0, 'selected': False, 'text': '<p>The key here is I need to script this.  Is there a cleaner way to extract the service status from <code>psservice</code>/<code>sc query</code>?  I\'m able to pipe it to <code>findstr "RUNNING"</code>, but there\'s got to be a better way.</p>\n'}, {'answer_id': 56916, 'author': 'busse', 'author_id': 5702, 'author_profile': 'https://Stackoverflow.com/users/5702', 'pm_score': 1, 'selected': False, 'text': '<p>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:</p>\n\n<p><a href="http://www.robvanderwoude.com/vbstech_proc_service.html" rel="nofollow noreferrer">http://www.robvanderwoude.com/vbstech_proc_service.html</a></p>\n'}, {'answer_id': 148431, 'author': 'spoulson', 'author_id': 3347, 'author_profile': 'https://Stackoverflow.com/users/3347', 'pm_score': 3, 'selected': False, 'text': '<p>After working on this for a while, I came up with the following VBScript.  Feel free to comment/improve.</p>\n\n<pre><code>\'\n\' Remotely reboot a server and\n\' wait for server to come back up.\n\'\n\' Usage:  cscript /nologo /E:VBScript RebootWait.vbs &lt;Server Name&gt;\n\'\n\' Shawn Poulson, 2008.09.11\n\'\n\n\'\n\' Get server name from command line\n\'\nIf WScript.Arguments.Count &lt;&gt; 1 Then\n   ShowUsage()\n   WScript.Quit(1)\nEnd If\n\nServerName = WScript.Arguments(0)\n\n\'\n\' Verify server is currently up\n\'\nWScript.StdOut.WriteLine Now &amp; ": Verify server \'" &amp; ServerName &amp; "\' is currently up..."\nIf Not IsAvailable(ServerName) Then\n   WScript.StdOut.WriteLine "Error: Server is down.  Reboot aborted!"\n   WScript.Quit(1)\nEnd If\nWScript.StdOut.WriteLine Now &amp; ": Server is up."\n\n\'\n\' Reboot server\n\'\nWScript.StdOut.WriteLine Now &amp; ": Rebooting server \'" &amp; ServerName &amp; "\'..."\nRebootStatus = RebootServer(ServerName)\nIf RebootStatus &lt; 0 Then\n   WScript.StdOut.WriteLine "Error: Reboot returned error " &amp; RebootStatus\n   WScript.Quit(1)\nEnd If\nWScript.StdOut.WriteLine Now &amp; ": Reboot command was successful"\n\n\'\n\' Wait for server to come down\n\'\nWScript.StdOut.Write Now &amp; ": Waiting for server \'" &amp; ServerName &amp; "\' to go down..."\nWaitCount = 0\nDo While IsAvailable(ServerName)\n   WaitCount = WaitCount + 1\n   If WaitCount &gt; 60 Then \' 5 min timeout\n      WScript.StdOut.WriteLine "Error: Timeout waiting for server to come down!"\n      WScript.Quit(1)\n   End If\n   WScript.StdOut.Write(".")\n   WScript.Sleep(5000)\nLoop\nWScript.StdOut.WriteLine "Success!"\nWScript.StdOut.WriteLine Now &amp; ": Server is down."\n\n\'\n\' Wait for server to come back up\n\'\nWScript.StdOut.Write Now &amp; ": Waiting for server \'" &amp; ServerName &amp; "\' to come back up..."\nWaitCount = 0\nDo While Not IsAvailable(ServerName)\n   WaitCount = WaitCount + 1\n   If WaitCount &gt; 240 Then \' 20 min timeout\n      WScript.StdOut.WriteLine "Error: Timeout waiting for server to come back up!"\n      WScript.Quit(1)\n   End If\n   WScript.StdOut.Write(".")\n   WScript.Sleep(5000)\nLoop\nWScript.StdOut.WriteLine "Success!"\nWScript.StdOut.WriteLine Now &amp; ": Server is back up after reboot."\n\n\'\n\' Success!\n\'\nWScript.Quit(0)\n\n\nSub ShowUsage()\n   WScript.Echo "Usage: " &amp; WScript.ScriptName &amp; " &lt;Server name&gt;"\nEnd Sub\n\n\' Returns:\n\' 1 = Successfully issued reboot command\n\' -2 = Could not reach server\n\' -3 = Reboot command failed\nFunction RebootServer(ServerName)\n   Dim OpSystem\n   On Error Resume Next\n   For Each OpSystem in GetObject("winmgmts:{(Shutdown)}!\\\\" &amp; ServerName &amp; "\\root\\CIMV2").ExecQuery("select * from Win32_OperatingSystem where Primary=true")\n      On Error GoTo 0\n\n      If IsObject(OpSystem) Then\n         \' Invoke forced reboot\n         If OpSystem.Win32Shutdown(6, 0) = 0 Then\n            \' Success\n            RebootServer = 1\n         Else\n            \' Command failed\n            RebootServer = -3\n         End If\n\n      Else\n         RebootServer = -2\n\n      End If\n   Next\nEnd Function\n\n\' Return True if available\nFunction IsAvailable(ServerName)\n   \' Use Windows RPC service state as vital sign\n   IsAvailable = (GetServiceState(ServerName, "RpcSs") = "Running")\nEnd Function\n\n\' Return one of:\n\'  Stopped, Start Pending, Stop Pending,\n\'  Running, Continue Pending, Pause Pending,\n\'  Paused, Unknown\nFunction GetServiceState(ServerName, ServiceName)\n   Dim Service\n   On Error Resume Next\n   Set Service = GetObject("winmgmts:\\\\" &amp; ServerName &amp; "\\root\\CIMV2:Win32_Service=\'" &amp; ServiceName &amp; "\'")\n   On Error GoTo 0\n   If IsObject(Service) Then GetServiceState = Service.State\nEnd Function\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/56644', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3347/']