Skip to content

Instantly share code, notes, and snippets.

@ninmonkey
Last active November 30, 2021 02:40
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ninmonkey/2c82867e5b8d6ce9b544aa64cb997b04 to your computer and use it in GitHub Desktop.
Save ninmonkey/2c82867e5b8d6ce9b544aa64cb997b04 to your computer and use it in GitHub Desktop.
Powershell Documentation Examples.md

Here's a couple things to consider for what, and how much to comment.

Who is the function for?

  • is this function internal only?
  • or will users see and use it?
  • If I come back in 9 months when the details aren't fresh, what will you need to know?
  • do parameters need details? would comments be too verbose? Like if the function is named ShortenString, and the params are [string]$Text, [int]$MaxLength , there's not much to say.

At least 1 line for .Synopsis

It depends how user facing the function is. I try to basically always use a 1-line comment of #. I try to have at least a single line comment, even if it's simple like

function Write-Newline {
    # outputs n-number of newlines
   param( [int]$NumLines )   
   ("`n" * $numLines) -join ''
}

But with a tiny bit more, the .synopsis keyword makes it so Get-Help, and, VS Code, etc can give you some information -- verses a blank function signature. Future you will probably thank previous you.

function Write-Newline {
   <#
   .synopsis
     outputs n-number of newlines
   #>
   param( [int]$NumLines )   
   ("`n" * $numLines) -join ''
}

.Inputs

I don't use that field because that's generated from parameter-comments. like:

function Invoke-TextTemplate {
    param(
        # Throw errors on any missing value? Or silently continue
        [Parameter()][switch]$Strict
    )
}

.Outputs

outputs It's really free-form from between people or projects. Sometimes a concrete type doesn't make sense. Other times it does. If a type is either $null or type x I like to write it as a typed union. Example returning null or an array of strings:

.outputs
    [ [string[]] | None]

or

 .outputs
    either [string] otherwise [Management.Automation.CommandInfo] when using -passthru

If it's always a fixed type, I will use [outputtype('someType)].

A little more

This is almost more comments than needed, however, this is a case where .link is important. There's a concrete type, so I included that.

function Find-ObjectProperty {
    <#
    .synopsis
        Sugar to enumerate object properties 
    .example
        PS> Get-Date | Find-ObjectProperty
        PS> Get-Item . | IterProps | Where-Object Name -Like 'PS*'
    .link
        ClassExplorer\Find-Member
    .link
        Microsoft.PowerShell.Utility\Get-Member
    #>
    [Alias('IterProps')]
    [outputtype('PSMemberInfoCollection[PSPropertyInfo]')]
    [cmdletbinding()]
    param(
        # any object
        [Parameter(Mandatory, Position = 0, ValueFromPipeline)]
        [object]$InputObject
    )
    process {
        $InputObject.psobject.properties | Sort-Object -Unique
    }
}

.linking to others

You can link to functions in your own module, external modules, or even a url. If the name might collide, you might want to note that.

.link
    Microsoft.PowerShell.Utility\Write-Host
.link    
    Pansies\Write-Host

Here's a case where more examples is useful ClassExplorer/FindMemberCommand.cs to/from ClassExplorer/Find-member.md

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment