I’ll be honest, I am by no means an expert when it comes to PowerShell and there may be a good chance that if you’re reading this you have a lot more experience using PowerShell than I do. One thing I feel I do have though is a sense for good design and being able to at least engineer something that is easy to follow and understand (at least in my humble opinion!).
My first ‘real’ experience of having to work with and change an existing group of scripts came around 7 months ago. I remember browsing though these scripts trying to understand what was going on and at the same time trying to decide the best seams to introduce the changes I needed to make. It was quite challenging. Not only was I having to learn all this new syntax and fundamental concepts but I was having to understand the original intent of the author(s). There were no unit tests, documentation was sparse and the one thing that made this really difficult was just how much there was of it.
A few months passed, my experience grew and I was becoming more confident in my ability in the environment. I still made ‘amateur’ mistakes like failing to expand properties in variables when expanding them in strings but I was getting better. That project drew to a close and another one began, again my team inherited a group of scripts that had been developed previously and again I encountered the same problem. A wall of PowerShell that very much fell into the same trap as the scripts I had seen before. The challenge with these sets of scripts was that the only place they had been intended to run and could be tested was in our production environment. I remember thinking back then that there was literally no way I would be confident to execute scripts that I can’t understand against a production environment. There had to be a better way.
Do One Thing And Do It Well.Unix Philosophy
And there was, and it wasn’t that hard. In fact, all we needed to do was break code down and begin adding some unit tests as we went. My inspiration came from looking though Donovan Brown’s excellent PowerShell module for accessing VSTS, VSTeam. Being curious by nature, I wanted to get some understanding of how the module working and one of the first things that struck me was how the project was structured.
The image above shows how the source folder for the module has been structured, in particular notice the
Public folders. Inside the
Public folder there are several cmdlets each dedicated to performing a single function. Going up one folder and there’s a folder named
Test. This contains several Pester tests that exercise the functions within the module (this is something I’d like to cover in a separate post). By applying a similar folder structure to our own code we began to slowly tease apart each function of the script into its own cmdlet. We followed an almost cookie cutter approach such that each cmdlet followed the same patterns and structure. The biggest impact of this approach? We began to understand what was going on, our confidence in the code increased and we had understood where the code needed to be improved.
So I suppose my message to those of you that write Powershell modules and scripts is to think of your fellow developer, those that will later inherit the code that you’ve (hopefully carefully!) crafted. Stop building walls of script that only you understand or because it’s the quickest way to do it. Take a little bit of extra time and think about the composition of your project, trust me, those that come after you will thank you for it.