Here's a couple things to consider for what, and how much to comment.
- Who is the function for?
- At least 1 line for
.Synopsis
.Inputs
.Outputs
- A little more
.link
ing to others
- 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.
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 ''
}
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
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)]
.
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
}
}
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