#PowerShell Controller Script Template

#PowerShell Controller Script Template

When it comes to Windows PowerShell, in most instances, I deliver pretty much complex scripts to bridge the gap between management systems that cannot communicate directly with each other. Usually these script solutions will be hooked into a Whatever Automation Suite that has control over the IT workflows. A mandatory requirement is that the script passes information back to the caller, be it an exit code, a message string, or an API call, you name it. Therefore, I’ve written a PowerShell template for a controller script that already includes the code to deal with multiple logical steps, with exceptions, and passing back corresponding information. I decided to share a simplified edition of that template with the readers of this blog (it’s on GitHub). I consider it a good starting point to build a controller script, that leverages the tools, PowerShell functions, and modules to succeed.

Plain vanilla structure

The template is structured in multiple sections, that is (1) requirements, (2) comment-based help, (3) parameters, (4) private helper functions, (5) initialization, and (6) main (implemented as a huge try-catch-finally).

Initialization region

In this region the script prepares for returning information as follows:

Assuming that the script will fail an IsSuccessful variable will be set to $false.

A Result hashtable with a nested hashtable for each possible result, that is success, unknown failure, and all well-known failure results.

A ScriptResult variable will be initialized as an empty hashtable. At the end it will hold the relevant information for the caller.

A ScritResultOnError variable will be set initially to $Result.Unknown. In course of script processing that variable will be updated continuously with corresponding failure information.

Furthermore, in order to catch exceptions, the ErrorActionPreferece variable will be set to Stop which enables termination instead continuation in case of exceptions.

Main region

Basically, the main region is a huge try-catch-finally statement meaning that once a command within the try-ScriptBlock throws an exception, PowerShell will run the catch-ScriptBlock. In any case the finally-ScriptBlock will be run. This is plain vanilla as well.

The try-ScriptBlock, however, is divided into regions. Each logical step in completing the script task is represented by a region. Each region begins with an update for the ScriptResultOnError variable so that it holds corresponding script results just in case of downstream failure or rather exception. The actual commands for the region in question follow afterwards and yet other commands might be necessary to validate outcome. If the outcome doesn’t meet the requirements for the script to succeed, the region exits processing of the try-ScriptBlock with Break. The Break statement will directly lead to the finally-ScriptBlock. (I distinguish between ‘hard’ errors that is exceptions and ‘soft’ errors that is unfulfilled interim results. Hard errors lead to the catch-ScriptBlock. Soft errors don’t.) The final region inside the try-ScriptBlock is in charge to set the above mentioned IsSuccessful variable to $true, if applicable.

The catch-ScriptBlock will be used to log the exception message and the like.

The finally-ScriptBlock, finally, returns the script result to the script caller. In order to pass back correct information, it first sets the ScriptResult variable depending on IsSuccessful‘s value. If it is $true it will hold $Result.Success, if it is $false it will set to $ScriptResultOnError which holds the ‘latest’ failure results (see above). Ultimately, $ScriptResult contains a hashtable with one or more elements to return. The script template contains sample code to terminate script execution with an exit code.