Skip to content

Documentation and comments#

Comment-based help#

Practice: Comment-based help goes first inside the function body. Include sections in this order: .SYNOPSIS (one sentence, imperative mood), .DESCRIPTION (one paragraph per behaviour or parameter set), .EXAMPLE (at least one per public behaviour), .INPUTS, .OUTPUTS (matches [OutputType()]), .NOTES, .LINK. Use inline comments above each parameter (not .PARAMETER). Comments explain why, not what.

Why: Documentation lives close to the thing it documents (Principles). Help inside the body ensures Get-Help always finds it and makes it collapsible in VS Code. Explaining why preserves context that code alone cannot express — this is how knowledge becomes shared (Write it down, Context-first development).

How:

# Good
function New-UserAccount {
    <#
        .SYNOPSIS
        Create a new user account.

        .DESCRIPTION
        Creates a new user account with the specified username and email.

        .EXAMPLE
        New-UserAccount -UserName 'jdoe' -Email 'jdoe@example.com'

        .INPUTS
        None.

        .OUTPUTS
        [PSCustomObject]

        .NOTES
        Requires admin permissions on the target tenant.

        .LINK
        https://psmodule.io/MyModule/Functions/Users/New-UserAccount/
    #>
    [CmdletBinding()]
    param(
        # The username for the new account.
        [Parameter(Mandatory)]
        [string] $UserName,

        # The email address for the new account.
        [Parameter(Mandatory)]
        [string] $Email
    )

    # Validate before hitting the database — fail fast
    if ($Email -notmatch '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') {
        throw "Invalid email format: $Email"
    }
}
# Bad
function New-UserAccount {
    param($UserName, $Email)
    # Check email                          # States "what", not "why"
    if ($Email -notmatch '^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$') { throw 'Invalid' }
}