Modern software is complex; often so complex that it is simply too much for one person to hold onto the big picture while digging in to the minute detail of a specific bug or feature. The “Separation of Concerns” paradigm has emerged as a practical and effective way of managing this complexity; a concise description of Separation of Concerns can be drawn from Wikipedia:
The philosophy encapsulated in separation of concerns can be applied to the scripts we write; allowing us to build modules, scripts and functions that can are resistant to the unintended side effects that are common when working in large teams. It doesn’t seem as easy or as natural as it might in .NET or most other modern programming environments, but some simple techniques can help you to break down your scripts into smaller more maintainable pieces.
EXTRACTING CONFIGURATION FROM THE SCRIPT
Configuration changes frequently, it may even change between single executions of a script if you are executing one script against several different environments such as Development, Test/QA, UAT and Production. If you find yourself hard coding a connection string into a script consider extracting this configuration setting into an external file or environment variable.
Lets say we have a script that sends an e-mail:
Now the Technical Director wants to get the status report each time it is run, well that would require line 2 to be duplicated right? alternatively how about the following change:
would contain each e-mail address you wanted to send to on a line of it’s own:
There is now no reason to open the script to add, remove or change an email address. A simple unit test and gated build can validate the correctness of the contents of the file.
SEPARATING FORM FROM FUNCTION
The text of an e-mail changes infrequently; however when it needs to be altered the change may be made by someone who does not understand PowerShell. As in the previous example you don’t need to construct the message entirely in PowerShell; if you place the static parts of the message in an external file this can readily be changed without affecting the script.
There is a templating technique for filling in the dynamic portions of the message as documented by Brice Lambson; I have chosen to swap out the dollar signs that Brice uses in favour of curley braces:
You can then subsequently include the template as a separate text file:
Your script can then merge the data with the tokens:
I have included the a working sample of all of the files used in this blog post in a gist, including functionality to send a HTML Alternative View using the same template technique.