Be Mindful of Object Types when Writing Unit Tests and Performing Operational Validation in PowerShell with Pester

I recently wrote a Pester test that performs some basic operational validation (smoke tests) of SQL Servers. I’ve previously written similar tests as functions as shown in my “Write Dynamic Unit Tests for your PowerShell Code with Pester” blog article, but I decided to write this one as a script with the naming convention that seems to be recommended. The name of this particular test is “Validate-MrSQLServer.Tests.ps1“. You’re probably thinking “Validate” isn’t an approved verb and you’re right, but this isn’t a function, it’s a script.

Just because I decided to write a script instead of a function doesn’t mean that I can’t take advantage of features such as a Requires statement, parameter input along with parameter validation, and error handling. It just needs to be written as an advanced script like an advanced function that you’re probably already familiar with. Pester tests are simply written with PowerShell code, so why not take advantage of any language feature that you want?

Woohoo! Everything works great!


Not so fast. The first rule of writing unit tests was violated. Write the tests first and make sure they fail before writing any code (functions, scripts, etc). You might ask, how to do that for operational validation since you’re not testing any code? The obvious answer would be to write the tests before building the environment but that’s not possible when the environment already exists. In that scenario, the answer is to run the tests in a simulated environment where the servers and/or services don’t exist.

In this example, I’ll simply use the name of a SQL Server that doesn’t exist to simulate writing the operational tests before the environment is created:


Houston, we have a problem.” The problem is that one of the tests passes successfully when it should fail since it’s being run against a machine that doesn’t exist. In other words we have a false positive. Oh, and by the way, make sure the machine you’re testing against really doesn’t exist.

The funny thing is that based on the way the code is written, everything looks like it should work. So what’s the problem? The problem is an assumption was made for the type of objects that Test-Port returns. The “Open” property returns a string and it’s being compared to a Boolean.

Always double check the type of output you’re receiving instead of making assumptions:


To resolve this problem, the test can be changed to compare the output of Test-Port with the string ‘True’ instead of the Boolean $true.

This change is no longer necessary since the creator (PowerShell MVP Boe Prox) of the Test-Port function that I’m using has updated it so the “Open” property now produces a Boolean instead of a string. The Test-Port function can be downloaded from Boe’s PowerShell Scripts Repository on GitHub. I’ve added it to my MrToolkit module which can be downloaded from my PowerShell repository on GitHub.

The moral of the story here is don’t assume anything and make sure you’re comparing apples to apples and not strings to Booleans or vice versa.

The Validate-MrSQLServer.Tests.ps1 test shown in this blog article can be downloaded from my Operational Validation repository on GitHub.


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: