HOWTO: Microsoft Certification Exam Preparation Generator

If you’ve ever had to write a Microsoft certification exam, you know that the exam syllabus is available from a URL that looks like this:

https://www.microsoft.com/en-us/learning/exam-##-###.aspx

Where the ##-### is the specific exam you are writing.  You likely also know that  the way Microsoft presents this information is not ideal from a study guide perspective.  It’s broken into categories and from there is just a jumble of words including many, many “filler” words like “plan and configure” or “configure and troubleshoot”.

I am writing a new certification exam and I wanted a simple means to know what specific concepts to study and play with in my lab.  I realized that I should be able to write a PowerShell script that would download the HTML from the URL above, extract the exam syllabus text and then cut out all of the unnecessary words.  This would leave me with a clean “checklist” of keywords I need to Google and understand.

So I wrote that.

Continue reading

HOWTO: Build a Temperature Alert System using a Raspberry Pi

I recently had my furnace fail while I was away on business.  Fortunately there were no lasting consequences but it could have been a very bad day.  To try and minimize the risk of such issues in the future, I decided I wanted a temperature monitoring solution that would alert me if the temperature in the house dropped below a pre-defined threshold.  I looked at things like a Nest and the TempStick among others but all of them were hundreds of dollars and or relied on third party cloud services.  Before I invested in something like that, I wanted to see if I could build my own solution for cheaper and that was designed to meet my exact needs.  I recently received a Raspberry Pi from a friend and decided this would be a great use for such a project. 

Specifically I set out to have the following goals:

  • The Raspberry Pi would record the temperature from a dedicated external temperature sensor every 20 minutes and record that value into a SQL database along with the timestamp
  • The Raspberry Pi would host a webserver that would allow me to review the current and historical temperatures from anywhere using my mobile phone
  • The webpage would also include a generated graphical chart showing the historical temperatures so I can review for any odd behavior at a glance
  • The Raspberry PI would automatically email me if the temperature dropped below a defined threshold so I could make phone calls to take immediate action
  • The Raspberry PI would upload a file to my off-site website host during each scanning interval via FTP
  • A cron job would run on my off-site webhost that would look for that file and if that file was not updated for more than one hour would alert me that either a power or Internet failure occurred at my house

I’m happy to report I achieved all of the goals above and figured I’d should share how I did it below.  Keep in mind I am not a software developer and so this solution is the result of grabbing things from the Internet and cobbling them together and tweaking until it does what I want.   With that out of the way, let’s begin with what you need to create something like this for yourself.

Continue reading

HOWTO: Calculate Elapsed Business Hours Using PowerShell

Update: 4/11/2022:  An individual by the name of Adam Cook has taken the premise of this script and transformed it into a far more robust PowerShell module and published it on Github.  I wanted to ensure I gave his project all the visibility I could.  The Github page is available here:

https://github.com/codaamok/PSBusinessTime

Thanks Adam!

Have you ever needed to calculate how many business hours / working hours have elapsed between a specific date and now?  For example, you may have some metric that says something needs to happen within 4 business hours.  We define business hours in this case as 8AM to 5PM Monday to Friday and does not include statutory holidays.  How might you go about doing that?

I found myself in this situation and figured it would be common and spent far too much time Googling trying to find someone else who built a solution for this problem.  To my surprise, I was unable to find a single working example for PowerShell.  Lots of examples for other languages such as T-SQL but nothing for PowerShell.  I was therefore forced to solve this myself.

Hopefully this will help you if you ever find yourself in a similar situation.

Before we get into the code, I’d like to start with a quick demo.  In my situation, we have a ticketing system and we want to kick off a process any time a ticket remains untouched for more than 4 business hours so we need to determine how many business hours have elapsed since the last touchpoint on the ticket.

In our example, the last time the ticket was interacted with was on December 21st, 2018 at 14:43:11.  The current date in this example is Friday January 4th, 2019 at 13:41:56.

As we see in the screenshot below, after the ticket was last touched, 2 hours 16 minutes and 49 seconds elapsed until the end of that business day.  Since this was a Friday the next 2 days were Saturday and Sunday and so we don’t add up these times.  The next week is actually the Christmas break so we also don’t want to count any of these.

The first official day back is Wednesday January 2nd, 2019.  Since the current time is newer than this we can simply add in a full 8 hours.  We do the same for the 3rd.  Finally on the 4th, since the current time is 1:41PM, that means we have already elapsed an additional 5 hours 41 minutes since 8AM.

image

Continue reading

HOWTO: Force (really) WSUS Clients to Check in on Demand

You're most likely here because you are an IT administrator and you have a network that deploys Windows Updates via Windows Server Update Services or WSUS.  Perhaps you're relatively new to WSUS or you're a veteran that has been using the product since its inception.  In either case, you are mostly frustrated because even in the latest release of WSUS that there is no reliable way to force clients to check in and report their status.  You know about wuauclt /reportnow and /detectnow.  You may even be aware of the .NET method  (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow().

But despite having tried everything, you're at at a loss.  All you want is for your clients to report their current status into WSUS on demand.  Is that really too much to ask?  Actually, it might be.  If you google "force wsus client to check in to wsus server", you'll see almost 300,000 results.  And I swear I've read every single one of them and tried every single suggestion.  

I finally decided to take matters into my own hands. I built a lab environment consisting of a domain controller, a WSUS server and a client machine.  I then proceeded to deep dive with process monitor and packet analyzers to try and find a way to "trick" the WSUS client into thinking it's time to report in.  After many hours at this, I was just about to give up when I accidentally stumbled upon the magic command I was looking for.

Continue reading

HOWTO: Backup and View All Contents of an Android Device

This HOWTO is written primarily for my own future reference but hopefully it’ll help someone else too.

Let’s say you want to back up the entire contents of your Android device.  How do you do that?

1) Download the Android Debug Bridge (ADB) tool that comes with the Android SDK Platform Tools.  The link of which is available here: https://developer.android.com/studio/releases/platform-tools.html

2) You should end up with the ADB tool in the following location: c:\adb\adb.exe

3) On your mobile phone, go to Options / Developer Options / and enable USB Debugging

4) Connect your phone to your computer via a USB cable

5) Open a command prompt and type c:\adb\adb.exe backup -apk -shared -all -f c:/adb/backup.ab

6) On your phone, you’ll receive a prompt.  Enter your password and choose “Backup my Data”  You will be prompted to enter the decryption password.  Remember this password as you’ll need it to view the contents of the backup

7) Wait for this process to finish.  It will take a while depending on how much data you have on your device

Continue reading

HOWTO: Generate a Microsoft Exam Checklist

Are you studying for a Microsoft certification exam?  If so, then you are probably familiar with the “Skills Measured” website that describes what will be covered on your exam.  If not, it looks something like this:

70-347_raw

I’m currently studying for my 70-347 – Enabling Office 365 Services exam.  The skills measured list above is a great starting point to use to determine what to search for and study and experiment with in your lab.  However the layout of the website has never appealed to me.  I would much prefer the text in Excel where I can annotate and color code it.  Unfortunately you can’t just copy and paste the text from the website into Excel as the HTML formatting makes everything a mess.

Continue reading

Is it just inflation?

I recently received a reminder to renew my AMA Plus membership.  2018 marks my 10th anniversary of having an AMA membership.  I pay in annual lump sum payments as it’s cheaper than the monthly option.  I was curious how much they’ve charged for the service over the last decade.  Have a look as I think it’s kind of interesting.  Here’s what I see:

  • In 2008, they charged me about $123 for the year for my initial sign up.  At this point since it’s a new service and we don’t have a baseline, we’ll use this as are reference frame
  • The following year, which is presumably the most likely period one would choose not to renew if they didn’t use the service, AMA greatly discounted the service making it far more likely that if someone was on the fence they would renew “just because”
  • You’ll note that from year 3 to year 9 the price increases at a nearly perfectly linear rate.  The jumps aren’t massive but if we look at the different of the 2009 payment compared to the 2016 payment we see it increased by a non-trivial 16%
  • Then, oddly, right before the end of the 10 year duration which is the next psychological marker, the price drops again.  Coincidence?
  • If you still renewed, then they know that they’ve got you and you won’t easily leave so what do they do, they increase the price by a larger amount than any previous period

image

All and all, the delta from the cheapest period to the most expensive is nearly 20%.  Recall that during this period, the membership plan remained constant with no changes and only one call was ever made to AMA in 2017, which coincidently is where the drop occurs.  The data suggests I should call in for service calls more often to get a greater discount on my renewals.  Therein of course lies the danger of drawing conclusions from this kind of data.

Now what happens if we compare this to inflation?  According to inflationcalculator.ca, a product that cost $123 in 2008 would cost $140.50 in 2018.  AMA is actually slightly under that.  It would seem the price increases really are just to cover inflation.

image

I found it interesting and figured I’d share.

HOWTO: Automate One-A-Day Photography

This will be a somewhat unusual HOWTO compared to those typically on this site.  In an effort to lose weight, I decided I wanted to take a photo of myself, once per day so I could track and further motivate the progress of regular exercise.  I then wanted to overlay the date each photo was taken as well as my weight on that day.  Finally, I wanted animate these daily photos into a GIF and upload it to my website so I can remind myself anywhere of my objective of losing weight.  The trick is I wanted to automate this entire process.  This meant I needed to find a solution for the following:

  1. Remotely control my camera to be able to take a picture and download it from an automated script
  2. Be able to programmatically crop the image from the camera to remove everything except the white background and myself
  3. Have a mechanism to be able to overlay text onto an existing image so I can add the current date any my weight data
  4. Obtain my latest weight from my Garmin Index scale via Garmin Connect and append it to the image
  5. Combine all of the previous images into an animated gif so I can watch my progress
  6. Automatically upload the animated gif to my website so I can view it anywhere

To complete this project, I decided to try and leverage my Canon S100 which I purchased as Canon’s top-end prosumer camera in 2012.  As I researched my options however, I discovered that Canon disabled any kind of remote control capabilities for this camera.  Fortunately I discovered that some very smart people created an alternative firmware for many popular Canon cameras including mine.  This firmware is called the CHDK or “Canon Hackers Developer Kit”.  This provides all sorts of additional features that are otherwise only available in Canon’s DSLR professional series cameras.  The one that I’m most interested in however is that the firmware provided the option to remote control my Canon S100.

Continue reading

Bank of Canada Interest Rate Changes Review

For those of you that live in Canada, you are no doubt aware that the Bank of Canada recently increased their policy rate from 0.5% to 0.75%.  I heard of a lot of media reporting that said this is the first change in 7 years.  I further read that we could expect further increases in the near future.  Since this policy rate directly impacts the rates that regular consumers get on any new loans and impacts even existing with variable rates, it seemed important to understand how this rate has fluctuated over the years.

To that end I did some research and found that on the official Bank of Canada website, you can download a CSV containing a list of every single day for the last 10 years and what the interest rate was on each of those days.  That is available here:

http://www.bankofcanada.ca/rates/interest-rates/canadian-interest-rates/

I wanted to know what the shortest number of days has been between interest rate changes.  Given the large scale impacts of changes to this rate in the country I assumed it would be something that was done exceptionally cautiously and once changed, a long waiting period would take place to review the impact.  According to my research though this assumption doesn’t appear to hold true over the last decade.

First though, a comment on the news reports that this is the “first change in 7 years”.  That claim turns out to be patently false.  The recent change represents the first increase in 7 years.  Over that time frame however we’ve seen 2 decreases to the rate.  Below are my findings:

Continue reading

HOWTO: PowerShell Function Return Quirk

Have you ever been using PowerShell, created a function that called another function and then tried to return data from the parent function only to discover that the returned data included more ‘stuff’ than you intended? This quick blog post demonstrates why that is and presents one workaround to prevent it in the future.

Clear-Host

Function Show-OutputMessage
{
    # Note that the only thing this function does is write to the pipeline.  It does NOT return any data.
    Write-output "An important message"
}

Function Run-Function
{
    # Inside a function, we call a sub function that inside that calls write-output. 
    Show-OutputMessage

    # Let's assume this parent function performs some kind of operation that returns a status code.  So the only thing we want to return is the status, ie:
    return "OK"
}

$Status = Run-Function
if($Status -ne "OK") { write-host "It's broken" -ForegroundColor Red } else { write-host "It's working” -ForegroundColor Green }

Consider the code above.  Pay attention to the Run-Function.  Let’s say this function performs some operation and then returns a status code upon completion.  In this example, it is returning “OK”.

You would then expect that the code at the end of the script that captures this return code and then performs and if operation on the result would return “It’s working” since it returned OK.  But it doesn’t.  If we run this code, you know what we get?

image

Why is that?

It turns out that unlike other programming languages, PowerShell returns everything that happens inside a function regardless if you use the return function or not.  So in the example above, we used Write-Output to write a message to the pipeline.  This was then returned along with the “OK” from the parent function resulting in an array of:

[0] “An important Message”

[1] “OK”

This is why the if ($Status –ne “OK”) doesn’t work since it’s trying to compare an object to a string.

So what’s the fix?  You need to ensure that the ONLY thing your function returns is the data that you want.  In this case, we don’t want Show-OutputMessage to be returned so we have to send its output to Null as in:

$null = Show-OutputMessage

Now the only data being returned is your “OK” status so the if statement works as expected.

image

The moral of the story is be very careful with what you add to the pipeline while in a function if you care about the return value since it likely isn’t going to be what you expect it to be.