Test your web access with PowerShell

I had a few issues yesterday with intermittent access to the internet. Some sites worked, others didn’t. The ones that didn’t work weren’t resolving via DNS, and the ones that did work didn’t always display correctly (presumably due to bits of them being sourced from other DNS domains that weren’t resolving).

I wanted a way of checking when the problem had been fixed so wrote this PowerShell script.

In the process of doing this, I wrote a fairly simple way of displaying a table with one column with text in a different colour.

The script takes its input from a hashtable consisting of a URL to a page/site, and some text to look for on the page that would be displayed if everything is working normally. The script does three tests:

  1. Does the site resolve via DNS
  2. Did the page load at all
  3. Was the expected text found on the page

I’ve not included a ping test because some web servers/VIPs don’t allow pinging, and in any case the result of this test would mostly be the same as “Did the page load at all”. If you want to add that in though it’d be pretty easy. Also, if the DNS test fails the script does not blindly plough on and try and retrieve the web page anyway, so it is moderately efficient.

The downside to using a hashtable is that you can’t have duplicate “names” in there, so if you tried to test two different pages from the same DNS domain it’d fail when building the results hashtable. I decided to use hashtables because I don’t use them very much and wanted to play with them, and because I knew the limitation wouldn’t be a problem based on what I want to test.

The output looks something like this:
InternetTester

I’ve added some comments so you can work out what’s going on, but it’s pretty straightforward. Here’s the script:

# Create hashtable for sites to be tested
$Sites = @{}

# Stop progress bar appearing during Invoke-WebRequest
$ProgressPreference = "SilentlyContinue"

# Add sites hashtable
# Format is: <URL to be retieved>,<text to find on that page>
$Sites.Add("http://windows.microsoft.com/en-us/windows-10/upgrade-to-windows-10-faq","Upgrade to Windows 10: FAQ - Windows Help")
$Sites.Add("http://www.google.co.uk/","I'm Feeling Lucky")
$Sites.Add("http://www.bbc.co.uk/news/education-35043243","Universities suffer cyber-attack")
$Sites.Add("http://www.twitter.com/","Welcome to Twitter")
$Sites.Add("http://www.itv.com/","The ITV Hub - The home of ITV")
$Sites.Add("https://netsight.ja.net/Public/HomePage.aspx","Welcome to Netsight")

# Loop forever (Press Ctrl-C to stop the script)
while ($true)
{
    $Results = @{}
    $MaxSiteLength = 0

    foreach($Site in $Sites.GetEnumerator()){
        $x = $Site.Name -match "//.*?/" # regex with "lazy" wildcard to get DNS domain name from URL
        $SiteName = $matches[0] -replace "/",""
        
        # Find the longest site name so results can be displayed neatly in a table
        if($SiteName.Length -gt $MaxSiteLength){
            $MaxSiteLength = $SiteName.Length
        }

        # Clear the variable used to hold the page content
        # If Invoke-WebRequest fails this would otherwise contain the previously tested page
        $Page = $null

        # Check the DNS is resolving correctly
        try{
            $x = Resolve-DnsName -Name $SiteName -DnsOnly -NoHostsFile -QuickTimeout -ErrorAction Stop
            try{
                # DNS is OK, fetch the page
                $Page = Invoke-WebRequest -Uri $Site.Name -TimeoutSec 1 -ErrorAction Stop
                if($Page.Content -like ("*"+$Site.Value+"*")){
                    # Everything is good
                    $Results.Add($SiteName,"OK")
                }else{
                    # The page loaded but the text wasn't found
                    $Results.Add($SiteName,"Page Text Warning")
                }   
            }
            catch{
                $Results.Add($SiteName,"Page Load Fail")
            }
        }
        catch{
            $Results.Add($SiteName,"DNS Fail")
        }
    }

    # Display the results
    Clear-Host
    # Write the table header
    Write-Host ("Site".PadRight($MaxSiteLength+2)+"Result")
    # Sort the sites into alphabetical order - hashtables display randomly otherwise
    foreach($Result in ($Results.GetEnumerator() | Sort-Object -Property Name)){
        # Look for keywords in the result text and set the colour variable appropriately
        switch -Wildcard ($Result.Value)
        {
            "*ok*" {$ForegroundColour = "Green"}
            "*warning*" {$ForegroundColour = "Yellow"}
            "*fail*" {$ForegroundColour = "Red"}
            Default {$ForegroundColour = "Gray"}
        }
        # Display the site name, padded to ensure the results line up neatly
        Write-Host $Result.Name.PadRight($MaxSiteLength+2) -NoNewline
        # Display the result in colour
        Write-Host $Result.Value -ForegroundColor $ForegroundColour
    }
    Get-Date -Format s
    Start-Sleep -Seconds 15
}
This entry was posted in PowerShell and tagged , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s