Home > PowerShell > Power Ping : A script to monitor your server restart

Power Ping : A script to monitor your server restart

Goal:

To monitor the restart status of a computer. That means, to know what happened after initiating the restart; whether it rebooted? failed to initiate the reboot? failed to come back online?. This scripts helps to easily answer these questions.

Today I restarted one  server and kept a continues ping to know when it comes online. The command prompt window got buried behind other windows, as I switched from it to take care of some other task meanwhile. I completely forgot that I should monitor that ping output to determine if the server is going down and coming back or not. When I looked at the ping status it is showing replies…. Now I don’t know if went down and came back or never went down. Also I what would have happen if the server went down but had problems in coming up? Nothing will happen than increased service outage which is costly to the organization.  With all these thoughts, I logged into the server and checked uptime of it to confirm that it is rebooted.

At that moment I got a thought to write a simple script which monitors the server restart and alerts me after a certain timeout with the status? My script should also alert me in case my server fails to go down and if it fails to come up as well. In addition it should notify me when the server comes back online. My script is ready with initial functionality to check the status, but when it comes to notification, I want to have something different and fancy. Email will definitely do, but I don’t know when I will open INBOX. So, what I have done is configured system tray notifications with alert messages(thanks to jdhitsolutions for sample code ). Now I am ready with the script I want, Restart-Monitor.ps1

Initially I have used test-connection cmdlet to check the ping status of remote computer but it didn’t work the way I expected. So, I felled back to my old ping-host function.

Usage:

[PS]C:local>.Restart-Monitor.ps1 -computer server1 -timeout 10

Where server1 is the name of the remote server I am monitoring and timeout is the max time(in minutes) server takes to reboot.

Screenshots:

Successful Restart:

Failed to Start:

Failed to Shutdown:

****Disclaimer: Author is not responsible for any kind of damage made by this script. Use it at your own risk.

Code:(save this into restart-monitor.ps1 and excute it from powershell window)

Param (
 [Parameter(ValueFromPipeline=$False,Mandatory=$True)]
 [string]$computer,
 [Parameter(ValueFromPipeline=$False,Mandatory=$False)]
 [int]$timeout=5
)            

$MAX_PINGTIME = $timeout * 60
$max_iterations = $MAX_PINGTIME/5
$Notification_timeout = 10 # in seconds            

function Show-notification {            

param($type,$text,$title)            

#load Windows Forms and drawing assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
#define an icon image pulled from PowerShell.exe
$icon=[system.drawing.icon]::ExtractAssociatedIcon((join-path $pshome powershell.exe))
$notify = new-object system.windows.forms.notifyicon
$notify.icon = $icon
$notify.visible = $True
#define the tool tip icon based on the message type
switch ($messagetype) {
 "Error" { $messageIcon=[system.windows.forms.tooltipicon]::Error}
 "Info" {$messageIcon=[system.windows.forms.tooltipicon]::Info}
 "Warning" {$messageIcon=[system.windows.forms.tooltipicon]::Warning}
 Default {$messageIcon=[system.windows.forms.tooltipicon]::None}
}            

#display the balloon tipe
$notify.showballoontip($Notification_timeout,$title,$text,$type)
}            

function ping-host {
param($pc)
$status = Get-WmiObject -Class Win32_PingStatus -Filter "Address='$pc'"
if( $status.statuscode -eq 0) {
   return 1
} else {
 return 0
}
}            

if(ping-host -pc $computer) {
 Write-Host "$computer is online; Waiting for it to go offline"
 $status = "online"
 for ($i=0; $i -le $max_iterations; $i++) {
  if (!(ping-host -pc $computer )) {
   break
  }
  Start-Sleep -Seconds 5
  if($i -eq $max_iterations) {
   Write-Host "$computer never went down in last $timeout minutes"
   Write-Host "Check that reboot is initiated properly"
   show-notification -type "error" -text "$computer is still ONLINE; Check that reboot is initiated properly" -title "Computer is not rebooting"
   exit
  }
    }            

    Write-Host "$computer is offline now; monitoring for online status"            

} else {
    Write-Host "$computer is offline; Monitoring for online status"
    $status = "offline"
}            

for ($i=0; $i -le $max_iterations; $i++) {
 if ((ping-host -pc $computer )) {
  break
 }            

 Start-Sleep -Seconds 5
 if($i -eq $max_iterations) {
  Write-Host "Your computer never came back online in last $MAX_PINGTIME seconds"
  Write-Host "Check that nothing is preventing starup"
  show-notification -type "error" -text "$Computer is NOT coming online; Something is preventing its startup" -title "Computer failed to start"
  exit
 }
}            

Write-Host "Your computer is Online Now; Task done; exiting"
show-notification -type "info" -text "$Computer is online" -title "$Computer successfully restarted"
  1. November 15, 2010 at 12:07 pm | #1

    Nice.

    Now, you should also try pushing the content to jabber/gtalk/priv-twitter.
    That way if you’re online on your phone and away from desk, you’ll still get a notif.

  2. November 20, 2010 at 6:49 pm | #2

    I feel that is a overkill. I expect one to be around at least at desk when restarting any server.

  3. Brian
    February 2, 2012 at 10:53 pm | #3

    Great function, but what about if your WSUS server is pushing multiple groups at different hour intervals and you want to monitor multiple servers. What if a server hangs in the reboot process? Example:

    8 AM
    Server 1
    Server 2
    Server 3

    9 AM
    Server 10
    Server 11
    Server 12

    etc…

  4. Brett
    March 28, 2012 at 1:42 am | #4

    Hey I’d love to try this but I keep getting this error.

    Get-WmiObject : Invalid query
    At C:\install\scripts\restart-monitor.ps1:119 char:28
    + $status = Get-WmiObject <<<< -Class Win32_PingStatus -Filter "Address='$pc'"
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

    Thanks for any help you can offer,
    Brett

    • March 28, 2012 at 1:19 pm | #5

      Brett, please post the command lines arguments that you are using that helps me to comment better. Looks like the arguments passed to Win32_PingStatus are null.

  5. Brett
    March 28, 2012 at 8:39 pm | #6

    Hi, here is an example:
    c:\files\scripts\restart-monitor\restart-monitor.ps1 -computer usdbcl01a

    usdbcl01a is a servername, I’ve also tried the fully qualified name which has the same result.

  6. Brett
    March 28, 2012 at 8:40 pm | #7

    Hi, here is an example:
    c:\files\scripts\restart-monitor\restart-monitor.ps1 -computer usdbcl01a

    I’ve also tried the fully qualified name which has the same result.

    Thanks,

    • March 28, 2012 at 10:25 pm | #8

      I think the script is failing due to formatting errors. The double quotes and single quotes in the below statement were problematic. So, I changed the formatting to my new style which should work fine. Please get the latest copy of the code again from the article and try again.

      $status = Get-WmiObject -Class Win32_PingStatus -Filter “Address=’$pc’”

  1. No trackbacks yet.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>