My typical PowerShell Script header

Every script I write starts with the same header. It documents what the script does, who wrote it, and when — and it sets up the standard parameters and error handling that I use consistently.

The template

<#
.SYNOPSIS
    Brief one-line description of what the script does.

.DESCRIPTION
    Longer description. What problem does this solve?
    What are the prerequisites?

.PARAMETER ParameterName
    Description of the parameter.

.EXAMPLE
    .\ScriptName.ps1 -ParameterName "value"
    Description of what this example does.

.NOTES
    Author:  Scott McGrath
    Created: 2023-07-20
    Version: 1.0
    License: MIT — This script is provided "as is", without warranty of any kind,
             express or implied. The author accepts no responsibility for any damage,
             data loss, or other consequences resulting from its use. Use at your
             own risk.
#>

[CmdletBinding(SupportsShouldProcess)]
param (
    [Parameter(Mandatory)]
    [string]$ParameterName,

    [Parameter()]
    [switch]$WhatIfSwitch
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

Why each part matters

Comment-based help — the .SYNOPSIS, .DESCRIPTION, .PARAMETER, and .EXAMPLE blocks feed directly into Get-Help. Anyone who runs Get-Help .\ScriptName.ps1 -Full gets proper documentation.

[CmdletBinding(SupportsShouldProcess)] — gives you $WhatIf and $Confirm support for free. For scripts that make changes, this is essential. Pair it with if ($PSCmdlet.ShouldProcess(...)) around destructive operations.

Set-StrictMode -Version Latest — catches uninitialized variables, deprecated syntax, and other common mistakes at runtime instead of silently misbehaving.

$ErrorActionPreference = 'Stop' — turns non-terminating errors into terminating ones, so the script stops on any error rather than continuing with bad state.

A note on param blocks

Always declare your parameters explicitly. Avoid $args. Named parameters make scripts self-documenting and allow tab completion when calling the script from the terminal.

Licence

I include an MIT licence notice in every script I share publicly. The key part is the warranty disclaimer — scripts that modify system configuration, Active Directory, Exchange, or Azure resources can cause real damage if something goes wrong, and it’s important to be clear that anyone running your code does so at their own risk.

The MIT licence is a good fit because it’s widely understood, permissive, and its “as is” clause covers exactly this: no warranty, no liability, use at your own risk. You don’t need a full LICENSE file for a standalone script — a one-liner in .NOTES is enough to make the intent clear.