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:

#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:

function Test-ConsoleColor {

<#
.SYNOPSIS
    Tests all the different color combinations for the PowerShell console.

.DESCRIPTION
    Test-ConsoleColor is a PowerShell function that by default iterates through
    all of the possible color combinations for the PowerShell console. The PowerShell
    Community Extensions Module is required by the function.

.PARAMETER Color
    One or more colors that is part of the System.ConsoleColor enumeration. Run
    [Enum]::GetValues([System.ConsoleColor]) in PowerShell to see the possible values.

.PARAMETER Paragraphs
    The number of latin paragraphs to generate during each foreground color test.

.PARAMETER Milliseconds
    Specifies how long to wait between each iteration of color changes in milliseconds.

.EXAMPLE
     Test-ConsoleColor

.EXAMPLE
     Test-ConsoleColor -Color Red, Blue, Green

.EXAMPLE
     Test-ConsoleColor -Paragraphs 7

.EXAMPLE
     Test-ConsoleColor -Milliseconds 300

.EXAMPLE
     Test-ConsoleColor -Color Red, Green, Blue -Paragraphs 7 -Milliseconds 300

.INPUTS
    None

.OUTPUTS
    None

.NOTES
    Author:  Mike F Robbins
    Website: http://mikefrobbins.com
    Twitter: @mikefrobbins
#>

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:

[CmdletBinding()]
param (
    [ValidateNotNullOrEmpty()]
    [System.ConsoleColor[]]$Color = [System.Enum]::GetValues([System.ConsoleColor]),

    [ValidateNotNullOrEmpty()]
    [int]$Paragraphs = 5,

    [ValidateNotNullOrEmpty()]
    [int]$Milliseconds = 100
)

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

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

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

$BG = [System.Console]::BackgroundColor
$FG = [System.Console]::ForegroundColor
$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:

foreach ($BGColor in $Color) {
    [System.Console]::BackgroundColor = $BGColor
    Clear-Host

    foreach ($FGColor in $Color) {
        [System.Console]::ForegroundColor = $FGColor
        [System.Console]::Title = "ForegroundColor: $FGColor / BackgroundColor: $BGColor"
        Clear-Host

        Write-Verbose -Message "Foreground Color is: $FGColor"
        Write-Verbose -Message "Background Color is $BGColor"

        Get-LoremIpsum -Length $Paragraphs
        Start-Sleep -Milliseconds $Milliseconds
    }
}

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:

    [System.Console]::BackgroundColor = $BG
    [System.Console]::ForegroundColor = $FG
    [System.Console]::Title = $Title
    Clear-Host

}

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.

ยต