"What is simple, is understood. What is understood, is executed." -Anonymous

In this post, learn how you can perform infrastructure testing in your environment using the PowerShell testing framework, Pester! You'll learn by following along with a story of how I learned by building a domain controller.

Pester, for the longest time, was intimidating to me early in my PowerShell journey. I'm still wondering what exactly it was that made me think that way. Was it being too busy just trying to learn what I needed for that moment, or was it that I didn't see how I could implement it into my suite of scripts? I don't have any good answers.

What is Infrastructure Testing?

Infrastructure testing is an informal term to mean running checks against various infrastructure components and configuration. The end goal is to ensure servers, network equipment, workstations, storage, anything in your environment is how it's supposed to be.

Whether the state was performed via script or manually doesn't matter. All that matters is that everything is configured how you would expect.

Infrastructure testing can be a lot of things. But to narrow the scope a bit and show you how to run infrastructure tests with the Pester testing framework, I'll be covering a story on how I learned how to run tests by building a domain controller.

The Scenario

I'm a sysadmin by trade and recently had experienced some system issues after performing some typical routine maintenance. Some of this work I had scripted by referencing the original checklists provided to me when I first started doing this work. This particular cycle, the checklist wasn't enough.

I had just finished rebooting a group of servers, plus a couple of domain controllers. This was a new environment and older systems were to be removed. This wasn't quite complete. Queue DNS issues.

Unaware that two legacy domain controllers were still present in this network I focused only on the two new domain controllers. Manual service checks showed everything was fine, yet my IIS and SQL servers were not functioning. I spent about an hour double and triple checking my work, making sure it wasn't a Windows update that was causing the problem. Then I found out the legacy DCs had not yet been fully demoted.

I was a bit troubled and embarrassed by this situation and set out to find a way to add some additional automated checks to my process. I had been hearing for a while now about a PowerShell module called Pester and how it could take my PowerShell scripting to a new level.

What Is Simple.

After reading a few blogs, watching some YouTube videos and reading the documentation on GitHub, was was very surprised at how easy this was to get started by doing simple infrastructure tests. I set out to build a test that would prove the health and functionality of my domain controllers.

Pester is a Domain Specific Language (DSL) that provides a framework for doing unit testing of PowerShell code. It's also very handy for performing infrastructure testing for hardware and software if PowerShell can interact with the endpoint. I'm not going to dive into the details here (Buy Adam Bertram's The Pester Book for that!) but the basics a sysadmin needs to know are four key terms:

  1. Describe - Exactly what it means. Describe the test you are performing.
  2. Context - Think of this as describing the subset of tests.
  3. It - The actual description of what you are testing and how you are obtaining a value.
  4. Should - what resulting value you are expecting when the test is performed.

You should also know that red is bad and green is good.

Is Understood.

My first tests focused on the basic services, ports and network response of just two domain controllers. I needed to test ping response, port 53 response, Active Directory Web Services, Active Directory Domain Services, DNS Server, NetLogon, Kerberos Key Distribution Center, and replication status.

All I needed to do was create some simple one-liners to return a value so that Pester could make the determination of a pass or fail scenario.

What Is Understood.

In the below example, this is a simple it block that defines how I'm going gather the necessary value:

It -Name "$DC01 Netlogon Service is Running" {
    $Netlogonsvc = Get-Service -ComputerName $DC01 -DisplayName 'Netlogon'
    $Netlogonsvc.Status | Should -BeExactly 'Running'
}

Is Executed

As you can see in the above it script block, I first set out to define a variable a simple PowerShell one-liner to get all the objects of the NetLogon service. I then harness the member property Status which returns a clean, single object value which is then passed on to the should block.

For this test to pass, the value must be exactly Running. The below example is a screenshot from a sample test:

Test Example

As you can see, the test domain controller reported that the service status was indeed in a running state, thus passing the test. My mind begins racing of all the infrastructure I can test now and how I can incorporate that into my automation routines.

But Wait, There's More!

During my initial development process, I created a test that met exactly what my requirements were and worked very well. However, it was not as portable as it could be. I decided to tweet about how excited I was to have made my first Pester test, that it worked and that it was very fast.

And the highlight of my day:

I also had some really great interactions with other IT pros also working on similar projects.

I put this code up on my GitHub repo and someone forked the project, added some code that took away the need for me to manually assign domain controller FQDNs, but also enhanced testing of replication status!

Now I have an awesome, highly portable, and useful tool that everyone can use. And it all started with a DNS problem.

Conclusion

I hope that my story inspires you as a sysadmin to take a little time out of your day and give Pester a try. It has not only encouraged me to do more infrastructure testing but it's also forcing me to start looking at things from a testing and validation viewpoint.

With Pester, I can run tests that allow me to say with a little more authority, that yes, systems are running to current specifications. I say that because there's always going to be that one situation, that regression that can occur. Pester allows for me to add additional tests without throwing out an entire test. Just add another context / it / should block and save. All future tests now have the regression test implemented.

From one seasoned sysadmin to another; Do yourself a favor. Learn Pester, and write some infrastructure tests!

If you'd like to learn more about Pester, be sure to check out the extensive blog post Write PowerShell Tests with Pester: Getting Started.