≡ Menu

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"

Comments on this entry are closed.

  • krish November 15, 2010, 12:07 pm

    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.

  • Sitaram Pamarthi November 20, 2010, 6:49 pm

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

  • Brian February 2, 2012, 10:53 pm

    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…

  • Brett March 28, 2012, 1:42 am

    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

    • Sitaram Pamarthi March 28, 2012, 1:19 pm

      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.

  • Brett March 28, 2012, 8:39 pm

    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.

  • Brett March 28, 2012, 8:40 pm

    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,

    • Sitaram Pamarthi March 28, 2012, 10:25 pm

      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'”

  • Perry Harris February 14, 2013, 2:25 am

    Great script. I had done something similar in VBS a long time ago, but lost it. Nice to see this done in PowerShell. I did notice that on line 17, it looks like two lines got put together.
    [reflection.assembly]::loadwithpartialname(“System.Windows.Forms”) | Out-Null[reflection.assembly]::loadwithpartialname(“System.Drawing”) | Out-Null
    Should be:
    [reflection.assembly]::loadwithpartialname(“System.Windows.Forms”) | Out-Null
    [reflection.assembly]::loadwithpartialname(“System.Drawing”) | Out-Null

    Once again, thank you for the great script.

  • Daniel January 28, 2014, 2:23 pm

    Hi,

    When the script finish I get this error message:

    PS U:\> .\power-ping.ps1 -computer xxx -timeout 480
    xxx is offline; Monitoring for online status
    Your computer is Online Now; Task done; exiting
    The term ‘Out-Null[reflection.assembly]::loadwithpartialname’ is not recognized as the name of a cmdlet, function, scri
    pt file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correc
    t and try again.
    At U:\power-ping.ps1:17 char:120
    + [reflection.assembly]::loadwithpartialname(“System.Windows.Forms”) | Out-Null[reflection.assembly]::loadwithpartialna
    me <<<< ("System.Drawing") | Out-Null
    + CategoryInfo : ObjectNotFound: (Out-Null[reflec…withpartialname:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

    Why is that?

    • Steve Jones November 16, 2019, 6:38 pm

      I know this is an old post, but I just found this site and the script is great. The problem you’re having with the “out null” error also happened to me. The problem is that 2 commands got pasted together: #load Windows Forms and drawing assemblies
      [reflection.assembly]::loadwithpartialname(“System.Windows.Forms”) | Out-Null
      [reflection.assembly]::loadwithpartialname(“System.Drawing”) | Out-Null

      The 2 lines should start with “[reflection.assembly]” but at least in my pasting, there was no linefeed between them so they ended up as one line. Go to the end of the first “| out-null” and just hit enter and re-save..

      • Wintel Rocks December 26, 2019, 3:46 pm

        Thanks for highlighting it. It is corrected now.

  • Amol Patil August 8, 2015, 7:03 pm

    Nice work done.
    But how this will work for Multiple servers ?

    • TechiBee August 23, 2015, 8:58 pm

      The approach that I have used in this script is not ideal for monitoring multiple computers restart. I will update here when I build that script. Don’t have a working one currently

      • Amol Patil September 6, 2015, 3:29 pm

        Sure, I also tried with this code and other way but no luck..
        Still trying…. I need this to use in one big activity.

      • Amol Patil October 1, 2015, 1:30 pm

        Hello,

        Any update on this with multiple server ping monitor ?

  • IFILL_P2V October 1, 2015, 5:33 am

    Restart-Monitor.ps1 working as intended. However trying to get this to work on multiple systems… be curious on that process…

  • Steve August 4, 2020, 8:10 pm

    Great script! I was wondering is there a way to also output the results to a log file in addition to the notification? I would like to run this around 2 in the morning and I’m not staying up to watch for the notification! LoL

  • Keith May 29, 2021, 7:38 am

    Love the script – could you add a secondary function to test if the server is ready to accept connections on 3389 as well?