Walkthrough: An example of how I write PowerShell functions

A couple of days ago I posted a blog article titled PowerShell function: Test-ConsoleColor provides a visual demonstration of the foreach scripting construct and today I thought I would walk you through that function step by step since it's what I consider to be a well written PowerShell function.

It starts out by using the Requires statement to require at least PowerShell version 3 or it won't run. It also requires that the PowerShell Community Extensions module be installed since it uses a function from that module and continuing without it only leads to errors:

1#Requires -Version 3.0 -Modules Pscx

The function is then declared using a Pascal case name that uses an approved verb along with a singular noun. Comment based help is provided just inside the function declaration. This isn't the only location where comment based help can be specified at, but it's my preferred location for it:

 1function Test-ConsoleColor {
 2
 3<#
 4.SYNOPSIS
 5    Tests all the different color combinations for the PowerShell console.
 6
 7.DESCRIPTION
 8    Test-ConsoleColor is a PowerShell function that by default iterates through
 9    all of the possible color combinations for the PowerShell console. The PowerShell
10    Community Extensions Module is required by the function.
11
12.PARAMETER Color
13    One or more colors that is part of the System.ConsoleColor enumeration. Run
14    [Enum]::GetValues([System.ConsoleColor]) in PowerShell to see the possible values.
15
16.PARAMETER Paragraphs
17    The number of latin paragraphs to generate during each foreground color test.
18
19.PARAMETER Milliseconds
20    Specifies how long to wait between each iteration of color changes in milliseconds.
21
22.EXAMPLE
23     Test-ConsoleColor
24
25.EXAMPLE
26     Test-ConsoleColor -Color Red, Blue, Green
27
28.EXAMPLE
29     Test-ConsoleColor -Paragraphs 7
30
31.EXAMPLE
32     Test-ConsoleColor -Milliseconds 300
33
34.EXAMPLE
35     Test-ConsoleColor -Color Red, Green, Blue -Paragraphs 7 -Milliseconds 300
36
37.INPUTS
38    None
39
40.OUTPUTS
41    None
42
43.NOTES
44    Author:  Mike F Robbins
45    Website: http://mikefrobbins.com
46    Twitter: @mikefrobbins
47#>

This allows the function help to be viewed as it would be for any PowerShell command:

test-consolecolor1b.jpg

CmdletBinding is specified to turn this function into an advanced function. All of the parameters are specified using parameter validation attributes, the Paragraphs and Milliseconds parameters use data type constraints, and the Color parameter uses a .NET enumeration to try to catch invalid input as early as possible in a standardized way. Default values are provided to make the function as easy to use as possible:

 1[CmdletBinding()]
 2param (
 3    [ValidateNotNullOrEmpty()]
 4    [System.ConsoleColor[]]$Color = [System.Enum]::GetValues([System.ConsoleColor]),
 5
 6    [ValidateNotNullOrEmpty()]
 7    [int]$Paragraphs = 5,
 8
 9    [ValidateNotNullOrEmpty()]
10    [int]$Milliseconds = 100
11)

I only want this function to be run in the PowerShell console:

1if ($Host.Name -ne 'ConsoleHost') {
2    Throw 'This function can only be run in the PowerShell Console.'
3}

Store the current console colors and title bar information in variables:

1$BG = [System.Console]::BackgroundColor
2$FG = [System.Console]::ForegroundColor
3$Title = [System.Console]::Title

The background color is set in one foreach loop and then a nested foreach loop sets the foreground color for each of the 16 available color options before the background color is changed again. It takes 256 total iterations to view all possible color combinations of the PowerShell console if you count both the foreach loops:

 1foreach ($BGColor in $Color) {
 2    [System.Console]::BackgroundColor = $BGColor
 3    Clear-Host
 4
 5    foreach ($FGColor in $Color) {
 6        [System.Console]::ForegroundColor = $FGColor
 7        [System.Console]::Title = "ForegroundColor: $FGColor / BackgroundColor: $BGColor"
 8        Clear-Host
 9
10        Write-Verbose -Message "Foreground Color is: $FGColor"
11        Write-Verbose -Message "Background Color is $BGColor"
12
13        Get-LoremIpsum -Length $Paragraphs
14        Start-Sleep -Milliseconds $Milliseconds
15    }
16}

Verbose output is also provided when the function is run with the Verbose parameter.

The colors and title bar are set back to the way they were before the function started using the variables that this information was previously stored in. The function declaration is closed with the last curly brace:

1    [System.Console]::BackgroundColor = $BG
2    [System.Console]::ForegroundColor = $FG
3    [System.Console]::Title = $Title
4    Clear-Host
5
6}

You could add things like pipeline input and error handling to improve it even further.

Remember to format your code for readability. Notice how the curly braces line up and the indentation of the code. Don't use positional parameters or aliases in scripts and functions or any code that you're sharing with others. Think about the next guy, it could be you.

I typically add my functions to a script module so I can simply call the function which auto-loads the module instead of having to manually locate and dot-source a .ps1 file. Note: Module auto-loading was introduced in PowerShell version 3.

Last but not least, you should place your code into some type of source control system such as GitHub. It doesn't matter if you're an IT Pro or a developer, you should be using source control <period>.

The Test-ConsoleColor function shown in this blog article can be downloaded from my PowerShell repository on GitHub.

µ