Skip to the main content.

ScriptRunner Blog

5 PowerShell scripting best practices – From runnable to professional code

Table of contents

Post Featured Image

How much time have you spent deciphering code from your colleagues or your predecessor? Often there is no rocket science behind the code chaos, but simple functions that only look complex at first glance.

Code Golfing might be funny on Reddit and save time in the console, but it has no place in professional scripts. Rather, you should follow the concept of simplicity – the motto here is: “Don’t make me think!”.

Replacing one line of code that makes your horizontal scrollbar break a sweat with several concise lines of code will save your colleagues a lot of frustration. In this article, I’ll show you 5 best practices for writing professional PowerShell code that brings you clarity, stability, and compatibility.

 

 

1. Clean formatting

The PowerShell interpreter does not care about pretty formatting – all code is rigidly processed one after the other. You could write your whole code in one line, as long as you separate single statements with a “;”. But this definitely does not benefit readability and at the latest when you want to work on your code again at a later time, you will regret this decision.

Especially at the beginning of their PowerShell career, users tend to have no consistency in their formatting. Here’s a direct comparison between unformatted code (Figure 1) and formatted code (Figure 2):

Detail eines PowerShell-Scripts: Alle Codezeilen sind am Zeilenanfang ausgerichtet.

Fig. 1: Unformatted PowerShell code

 
Detail of a PowerShell script: The bracketed code is indented

Fig. 2: PowerShell code formatted in brace style

As you can see in Figure 2, indentations give your text more structure and script blocks can be visually distinguished from each other. A space between operators (+, =, etc.) also provides clarity.

Opinions differ greatly on how to introduce script blocks. I’m a fan of the “one true brace style“: the opening brace is at the end of the introductory statement, the closing brace is on a separate line below the first character of the introductory statement. VSCode or various code-beautifiers can simplify your job here through auto-format features.

 

2. Use of comments

Let’s get real, you too have had to think through your own code after you wanted to update it after half a year. Code comments give you and your colleagues the opportunity to leave explanations for individual functions as a note in the code.

Single-line comments are opened with a hashtag/ hash. Comments over multiple lines are opened with<# and closed with#> (see Figure 3). Many editors also offer features to comment out selected lines via hotkey (VSCode: Ctrl + Shift + 7):

Detail view of a multiline comment within a PowerShell script

Fig. 3: A PowerShell comment that spans multiple lines

But beware: There is a danger of “over commenting” here – not everything in the code needs to be commented. Think about which lines of code are not understandable at first glance and focus on those.

In addition to the features mentioned above, comments can also be used to assign meta-information to functions. Keywords at this point are “parameter block” “synopsis” and “notes”. These are maintained in an exemplary manner in the ScriptRunner ActionPacks.

Through this meta information, help can be retrieved via Get-Help. The texts are of course freely selectable and adaptable to the module or function contents. The information is to be maintained here in the respective function. An example of a function that adds a file extension to files could look like in Figure 4:

Screenshot of a PowerShell function that contains an extensive list of meta information within a comment

Fig. 4: PowerShell function with detailed meta information within a comment 

Via Get-Help a PowerShell admin can query further meta information (Figure 5):

PowerShell output of the Get-Help cmdlet. A list of meta information is displayed.

Fig. 5: Output of the Get-Help cmdlet

 

3. Use of comprehensive variable names and conventions

I confess myself guilty – I also use $a, $b and sometimes even $c from time to time when initially writing my scripts. But only in the first development step.

Variable names should be meaningful and reveal their content at the latest upon release. Lists should be named in plural, single elements in singular  – $user is different from $users.

PowerShell is not case-sensitive – but that doesn’t mean you should mix all possible variations. Which convention you choose is up to you – as long as you stick to it!

The following conventions have prevailed across all languages:


$snake_case
$PascalCase
$camelCase
$sHungarianNotation  # 's' at beginning means 'String'

 

4. No hard-coding!

Hard coding in scripts is one of the most serious anti-patterns! Not only does it make your code adynamic and rigid, it can also be a dangerous security risk!
Code snippet in which information is passed to a PowerShell script via parameter binding

Figure 6: Code snippet where server name and credentials are passed as parameters

I have known many admins who put usernames and even passwords or keys as plain text in scripts. Many lack know-how in this area. The magic word in this context is Parameter Binding. Information can thus be passed on to the script from the outside:

You can read more aboutCmdletBinding in the articles “PowerShell Asdvanced Functions” and “Parameter Binding Concepts in PowerShell”.

When a script is called, the parameters are used to pass the required information. For example, ScriptRunner Software Platform can access a secure password safe and pass passwords to the script without any security risk – the feature is called “Password Server Connector“.

 

5. Parameter splatting

In many cases you need many parameters behind a cmdlet. This not only looks messy, it also often leads to very long lines of code and thus awkward horizontal scrolling.

Hashtables can help simplify your code immensely. The technique I’m referring to is called PowerShell splatting. Its goal is to group parameters together within a hashtable.

For example, if we want to notify a service owner about the restart of their server by mail (see Figure 7), we need a lot of parameters (the “back-tic” at the end of the first line allowed me to stretch the code for the screenshot to two lines):

Detail view of a PowerShell command passing a set of parameters.

Figure 7: Command without PowerShell splatting, where parameters and values are listed individually.

The same functionality can be displayed much more nicely with a hashtable, as in Figure 8 (values have been hard-coded here for clarity).

Figure 8: The same command with PowerShell splatting. Parameters and values are in a hashtable, which in turn is passed to the command.

This method is possible for all cmdlet parameters and makes your code more maintainable due to the overview gained.

 

 

Conclusion

These best practices provide a good foundation for clear code. Especially beginners and intermediate users should implement these practices directly in their code because of the advantages mentioned above and not limit themselves to pure functionality.

Also, in many IT landscapes, code standards exist – scripts are thus checked for conventions and quality standards before they are published.

 

Related posts

5 min read

Mastering PowerShell with Get-Help

9 min read

Top ten tasks for Microsoft Purview PowerShell

10 min read

Pipeline-Ready: Advanced PowerShell functions

About the author: