Thursday, October 9, 2008

WAN Status with PowerShell

Recently I was looking at the talking ping script I blogged about a few weeks ago and I wanted to see how I could make it more useful whilst extending my knowledge of PowerShell. Well here's what I came up with.

Below is a script that will prompt for a server list, loop though the servers and ping them. Depending on the response it'll display a little data about the health of the link or the speed of the link.There is even an option that allows you to speed up the ping or slow it down. I found this usful to leave running in the background and after a day I had only sent 4kbps of ICMP data which is pretty low considering the usefulnes of the realtime information I had.

What I'm looking at in the script is firstly the response times and then the statuscodes. The response times will tell me how long the echo response takes in milliseconds, and the stauscode will tell me if the is a problem such as destination host unreachable or TTL expired in transit etc..

Below is the list of sites that I am pinging in this example but typically this would be a list of servers across multiple sites.

The output from a fast ping (speed was 250) can be seen below. I have inluded the time in the output which I figured is pretty useful as I wouldn't just be sitting there staring at the output.

As you can see, if you only have a few servers the output will pretty soon fill up. I have also colour coded the output so my eyes are drawn to the important output (once you get use to the colours that is).

So here I have slowed the scan right down (speed 10000) which takes almost 2 minutes to get through the small list of servers I have here.

Okay, and now here's the code. Please remember, I'm still very new to PowerShell and although this is functional, I know in a years time I'll look back and see how crap it is and how I probably could have done it with half the code.

# Script to test for responsiveness of hosts to pings and identify network problems
$Serverlist = Read-Host "Give me a server list dude!"
$PingSpeed = Read-Host "How fast shall I ping (150 is fast, 1000 is slow)"
Write-Host "Press Ctr + C to quit"
function Ping-Network {
$Time = [DateTime]::now
$results = gwmi -query "SELECT * FROM Win32_PingStatus WHERE Address = '$computer'"
#Testing Speed
if ($results.responsetime -gt 3500)
{Write-Host "$time $computer link is getting screwed! >2500ms" -BackgroundColor red -fore white}
if ($results.responsetime -gt 2000)
{Write-Host "$time $computer link is getting hammered! >2000ms" -ForegroundColor pink}
if ($results.responsetime -gt 350)
{Write-Host "$time $computer link is very slow >350ms" -ForegroundColor yellow}
if ($results.responsetime -gt 250)
{Write-Host "$time $computer link is very slow >250ms" -ForegroundColor cyan}
elseif ($results.responsetime -gt 50)
{Write-Host "$time $computer link isn't great >50ms" -ForegroundColor green}
# Testing errors
elseif ($results.statuscode -eq 11010)
{Write-Host "$time Ping to $computer timed out" -ForegroundColor red}
elseif ($results.statuscode -eq 11002)
{Write-Host "$time Ping to $computer Failed. Destination net unreachable" -BackgroundColor red}
elseif ($results.statuscode -eq 11003)
{Write-Host "$time Ping to $computer Failed. Destination host unreachable" -BackgroundColor red}
elseif ($results.statuscode -eq 11013)
{Write-Host "$time Ping to $computer Failed. TTL expired in transit" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11018)
{Write-Host "$time Ping to $computer Failed. Bad destination" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11012)
{Write-Host "$time Ping to $computer Failed. Bad route" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11008)
{Write-Host "$time Ping to $computer Failed. Hardware error" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11009)
{Write-Host "$time Ping to $computer Failed. Packet too big" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11011)
{Write-Host "$time Ping to $computer Failed. Bad request" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11001)
{Write-Host "$time Ping to $computer Failed. Buffer too small" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11016)
{Write-Host "$time Ping to $computer Failed. Source Quench" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11017)
{Write-Host "$time Ping to $computer Failed. Option too big" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11050)
{Write-Host "$time Ping to $computer Failed. General failure" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11032)
{Write-Host "$time Ping to $computer Failed. Negotiating IPSEC" -fore white -BackgroundColor red}
elseif ($results.statuscode -eq 11014)
{Write-Host "$time Ping to $computer Failed. Destination protocol unreachable" -fore white -BackgroundColor red}
elseif ($results.statuscode -ne 0)
{Write-Host "$time $computer may be down" -fore white -BackgroundColor red }
# These lines have been disabled as I don't really need to know if the link is okay,
# I only want to know about problems.
#elseif ($results.statuscode -eq 0)
#{Write-Host "$time $computer is good"}
END {}
#Loop through the function
$loop = 1
do {$computers = (Get-Content $serverlist)
foreach ($computer in $computers) {
if (Ping-Network $computer) {
# Slow down the network pings by increasing the start-sleep value.
Start-Sleep -Milliseconds $PingSpeed
until ($loop -gt 2)

I know there are a load of programs that can do this but it was an easy PowerShell project and I can easily tweak it to suit my needs. I hope this might be useful to someone else.

No comments: