Defensive PowerShellFailing Fast with Validation AttributesChristopher KuechBlockedUnblockFollowFollowingApr 13Attributes are tags developers add to their code to dictate information to the interpreter.
Attributes are most commonly used for defining cmdlet interfaces and there are plenty of guides online for leveraging PowerShell parameter attributes in your code, but virtually no guides for unleashing the full potential of attributes in your PowerShell code.
Defensive programmingPrograms should detect bad input and fail immediately when bad input is detected.
You always want to detect potential issues as early as possible and minimize the amount of code run after a precondition fails.
Terminating errorsIn most mainstream programming languages, if the program throws an uncaught error, the program stops running.
In shell scripting languages like bash and PowerShell, if the program encounters an error, the program continues to the next line by default.
To force PowerShell to always stop on error, set:Tell PowerShell to make all errors fatalDeclarative or ImperativeDeclarative code tells the interpreter what to do while imperative code tells the interpreter how to do it.
Consider these two equivalent implementations:Declarative vs Imperative implementationsThe declarative implementation is clearly more concise, telling the interpreter to simply validate that $n is between 0 and 10.
In contrast, the imperative solution requires more code and contains implementation details — boolean operations and error instantiation — that can otherwise be avoided with a declarative solution.
Validation attributes are declarative because they define when a value is valid.
Using AttributesDeclaring an attributeAttribute declarations require:Square bracketsThe attribute nameThe attribute parameters — sometimes empty, but always presentThe value that the attribute affectsThe form of an Attribute declarationDiscovering validation attributesIf you haven’t already, install Code and install the PowerShell extension to enable autocomplete in PowerShell, as well as linting.
The easiest way to find the available validation attributes is to start typing[Validate and look at the options in the autocomplete menu:Validation attributes are most easily discovered through VS Code’s autocompleteMost of these attributes are self explanatory, but you can always search online for them.
Note that the name we use to declare the attribute does not include the “Attribute” suffix shown on all the attributes in the autocomplete menu.
Placing Validation AttributesStarting simple: Attributes on variablesAttributes are applied whenever you bind a name to a value.
The simplest example of binding a value and name is with a variable declaration.
Using a validation attribute with a variable declaration adheres to the following form:Applying an attribute to a local variableFor example, the following code will throw an error if you enter a string that is not “ca”, “eu”, or “us”:Concrete example of applying an attribute to a local variableOnce you understand how validation attributes are used in the simplest case, you can see how the same concept applies to more advanced use cases, like when binding values to function parameters in a function invocation, or binding values to class properties in a class instantiation.
Validating user input: Attributes on functionsWhenever you have a function that accepts parameters, you can add validation attributes to your parameter definitions.
Defining validation attributes on function parametersThis is by far the most common use case, so you can easily find other resources that expand on this concept, as well as explain other types of attributes, such as the [Parameter(.
Unleashing the potential: Attributes on classesIf you haven’t already, check out my other article on why you should be using PowerShell classes.
You’ll learn why PowerShell classes are beneficial, specifically for type conversions and serialization/deserialization.
Classes combined with validation attributes and casting integrate perfectly together, unmatched in any other language I’ve seen.
You can apply validation attributes above the associated property declaration, and they will be run whenever you set the property value, such as when you cast a hashtable to the class or set the value in a constructor.
Defining a class with property validation attributesWhen you cast your hashtable to your class type, the validation attributes will ensure that the properties contain valid values.
Casting to objectsCommon use casesThese are some practical examples of validation attributes that you can integrate in your scripts.
Further ReadingAbout Function Advanced ParametersYou should be using PowerShell classes.