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.
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.
I feel that is a overkill. I expect one to be around at least at desk when restarting any server.
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…
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
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.
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.
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,
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'”
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.
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?
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..
Thanks for highlighting it. It is corrected now.
Nice work done.
But how this will work for Multiple servers ?
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
Sure, I also tried with this code and other way but no luck..
Still trying…. I need this to use in one big activity.
Hello,
Any update on this with multiple server ping monitor ?
Restart-Monitor.ps1 working as intended. However trying to get this to work on multiple systems… be curious on that process…
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
Love the script – could you add a secondary function to test if the server is ready to accept connections on 3389 as well?