Quick Learn – Automate App Server (Non Visual) Website Test

This is part II of this post: http://tommymaynard.com/quick-learn-automate-app-server-visual-website-test-2016. It might be beneficial to read that first.

It was minutes before my family needed to leave the house and start our Saturday, when my desire to monitor eight of my application servers hit. In a quick moment, I wrote three commands in three PowerShell consoles and left the house.

Before I show you what was in console one, I have to show and mention a couple functions on which it relied. These functions are a bit of a continuation of the link above. The Watch-MyApp function below, will visually and textually display indicators so that I know if my app servers’ websites are responding, or not. The -Visual parameter will open an instance of Internet Explorer for each server URL, so I can visually check the app servers’ websites (see the link to view this function).  Not using the -Visual parameter, which is how it’s used here, uses Invoke-WebRequest to determine a webpage’s status code. A 200 status code (OK response) means our webpage is up, and responding. If it’s not up, it’ll indicate a timeout warning. It could also produce a different status code, if the page is up, but produces something other than a 200 status code. Other more well-known status codes are the dreaded 404 (page cannot be found), or a 5xx error which indicates a problem with the web server. It may also be helpful to know that the $MyAppServers variable contains the default properties for five servers, returned from the Get-ADComputer cmdlet.

Function Watch-MyApp {
    Param (
        [switch]$Visual
    )
    
    If ($Visual) {
        $MyAppServers.Name | ForEach-Object {
            Open-InternetExplorer -Url "$_.myapp.mydomain.com"
        }
    } Else {
        $MyAppServers.Name | ForEach-Object {
            try {
                $StatusCode = (Invoke-WebRequest -Uri "http://$_.myapp.mydomain.com" -TimeoutSec 10).StatusCode
                "$StatusCode`: $_"
            } catch {
                Write-Warning -Message "$_"
            }    
        }
    }
 }

The first of my three consoles wrapped the function above, Watch-MyApp, in a never ending loop ($true is always true). Every minute it would get the date and time and write it to a log file. Immediately after that, it would run the function to get the status code of each web server, and append it to the same log file. A minute later and it does the same thing. Here’s the command and a sample from the log file it created.

Do {
    (Get-Date).ToString() | Out-File -FilePath 'C:\MyApp.txt' -Append
    Watch-MyApp | Out-File -FilePath 'C:\MyApp.txt' -Append
    Start-Sleep -Seconds 60
} While ($true)
2/21/2016 10:48:29 PM
200: appsrv01
200: appsrv02
200: appsrv03
200: appsrv04
200: appsrv05
2/21/2016 10:49:29 PM
200: appsrv01
200: appsrv02
200: appsrv03
200: appsrv04
200: appsrv05

The second console ran another endless Do-While loop. The difference, is that this loop’s job was to copy the file that was being updated by the command in the first console, to my Dropbox folder every ten minutes. Genius, right? While I could have, I opted to not have my first command write/overwrite the file directly in my Dropbox folder. I didn’t feel it was necessary to update Dropbox each minute for hours on end. When I was back home later, I changed this from ten minutes to 30 minutes, or 1800 seconds, as it was even less important to update Dropbox then.

Do {
    (Get-Date).ToString() | Out-File -FilePath 'C:\MyApp.txt' -Append
    Copy-Item -Path 'C:\MyApp.txt' -Destination 'C:\Users\tommymaynard\Dropbox\MyApp.txt' -Force
    Start-Sleep -Seconds 600
} While ($true)

What this meant is that while I was away, I was able to check Dropbox on my phone and quickly determine if there were any status codes other than a 200. Every ten minutes and there would be an update to my file that would include the status code results for each minute in the last ten.

The final console didn’t do much other than allow me to manually check the file in Dropbox, for something other than a date entry, and status code of 200. So far so good: None of the web apps returned anything more than a 200 status code. Maybe the change at the end of the day on Friday really did fixed things. Here’s the command I used to read the file and exclude lines that had a date and a 200 status code (all the lines unless there was a problem).

Get-Content -Path 'C:\MyApp.txt' | Where-Object {($_ -notlike '*2016*') -and ($_ -notlike '200*')}

But why visually scan the file myself, when PowerShell can do that too!? This third command could’ve also been an endless loop. It could’ve automated scanning the file for me, like I was doing already, and then could’ve been set up to send me an email using the Send-MailMessage cmdlet if it found something, other than the 200 status code. I could’ve avoided looking at the file in Dropbox and just watched my email. One better, and I could’ve had my command do email to text with a specially crafted email address. Here’s what I mean for US Verizon customers: http://www.verizonwireless.com/news/article/2013/06/computer-to-phone-text-messaging.html. Many days, it feels like PowerShell is only limited by what you can think do with it.

There have been times in my life where my wife will ask me, “How would people that don’t know computers, know how to do this?” I usually answer by saying, that “They wouldn’t,” or “I don’t know, I’m not that person.” The same thing applies here: “How would a Windows System Administrator know what to do if they hadn’t already learned PowerShell?” Those three commands might take someone new with PowerShell half a day to consider, and then write. Learn it while you don’t think you need it, because one day you will.

So, to recap, while I was away doing the family thing, my computer sat on the kitchen table at home, checked on eight app servers for me and updated a file in Dropbox, that I was able to check at times while we were away. PowerShell has a purpose, and without it, you’re losing yours.