PowerShell: A Function Template

“Stuff that saves time” is a pretty good credo for PowerShell.  With that in mind, if you’re going to write lots of functions a template can both save you a bit of typing and remind you about important bits to include.

Here’s mine, with a few comments afterwards.

<# .SYNOPSIS - .DESCRIPTION - .PARAMETER - .EXAMPLE - .NOTES Name : Verb-Noun Author : HerringsFishBait.com V1.0 Initial Version #>
function Verb-Noun
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory=$true,
        ValueFromPipeline=$true)]
        [Alias('Alias')]
        [PSObject]$SourceObject
    )
    BEGIN
    {
        Write-Verbose "$((Get-Date).ToShortDateString()) : Started running $($MyInvocation.MyCommand)"
        #Initialise Variables
    }
    PROCESS
    {
        #Get data from object depending on type
        If ($SourceObject -is [String])
        {
        }
        #Code to check for passed parameter name
        if (!($PSBoundParameters.ContainsKey('PSTExportFolder')))
        {
        }
    }
    END
    {
    }

Most of it is pretty straight forward but here’s a few notes;

<# .SYNOPSIS - .DESCRIPTION - .PARAMETER - .EXAMPLE - .NOTES Name : Verb-Noun Author : HerringsFishBait.com V1.0 Initial Version #>

It’s always a good idea to attach the comment-based help.  There’s quite a few fields you can complete for this if you want to but these are the ‘core’ I need to make sure the command is documented and which version it is.  Attaching the author is useful as I tend to leave bits of code scattered all over the place in work environments (for different projects, teams etc) so it means anyone else looking at the code can ping me for help.

function Verb-Noun
{
    [CmdletBinding()]

Always use the Verb-Noun standard structure for PowerShell.  Using a valid verb is a good idea too (use Get-Verb to find a good match for what you want to do).

I always add [CmdletBinding()] because it allows the use of Write-Verbose but there is quite a bit of other functionality it provides too.

    param
    (
        [Parameter(Mandatory=$true,
        ValueFromPipeline=$true)]
        [Alias('Alias')]
        [PSObject]$SourceObject
    )

I always try and make sure my functions can take parameters from the pipeline;  stringing multiple functions together while passing objects between them is both useful AND cool.

Unless I know for a fact the input will be something different I take a generic [PSObject] as the input parameter.  I then check for what’s passed in the main body (see below).

Aliases help with tying the function to other PowerShell cmdlets.

    BEGIN
    {
    }
    PROCESS
    {
    }
    END
    {
    }

I always add the standard BEGIN, PROCESS and END blocks even if I’m not going to use them;  I think it makes the functions easier to read.  Plus it’s a helpful reminder!

Any initialisation for the function goes in the BEGIN block as I don’t want it re-initialising for every object passed in from the pipeline.

Write-Verbose "$((Get-Date).ToShortDateString()) : Started running $($MyInvocation.MyCommand)"

A bit of code that writes when the function was started and what the function name was;  always useful for debugging.  I sometimes use a log-writing function instead of Write-Verbose here.

        #Get data from object depending on type
        If ($SourceObject -is [String])
        {
        }
        #Code to check for passed parameter name
        if (!($PSBoundParameters.ContainsKey('PSTExportFolder')))
        {
        }

These are templates for the two main bits of parameter verification I do; checking for the type of the passed object and then processing it and checking that a certain parameter has been passed.

I don’t use them all the time but it saves me looking up the syntax (especially for the $PSBoundParameters method)

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: