Make sure all files are encoded using UTF-8 (not UTF-8 with BOM), except mof files
which should be encoded using ASCII.
You can use ConvertTo-UTF8
and ConvertTo-ASCII
to convert a file to
UTF-8 or ASCII.
Use descriptive, clear, and full names for all variables, parameters, and functions. All names must be at least more than 2 characters. No abbreviations should be used.
Bad:
$r = Get-RdsHost
Bad:
$frtytw = 42
Bad:
function Get-Thing
{
...
}
Bad:
function Set-ServerName
{
param
(
$mySTU
)
...
}
Good:
$remoteDesktopSessionHost = Get-RemoteDesktopSessionHost
Good:
$fileCharacterLimit = 42
Good:
function Get-ArchiveFileHandle
{
...
}
Good:
function Set-ServerName
{
param
(
[Parameter()]
$myServerToUse
)
...
}
Use named parameters for function and cmdlet calls rather than positional parameters. Named parameters help other developers who are unfamiliar with your code to better understand it.
When calling a function with many long parameters, use parameter splatting. If splatting is used, then all the parameters should be in the splat. More help on splatting can be found in the article About Splatting.
Make sure hashtable parameters are still properly formatted with multiple lines and the proper indentation.
Bad:
Not using named parameters.
Get-ChildItem C:\Documents *.md
Bad:
The call is very long and will wrap a lot in the review tool when the code is viewed by the reviewer during the review process of the PR.
$mySuperLongHashtableParameter = @{
MySuperLongKey1 = 'MySuperLongValue1'
MySuperLongKey2 = 'MySuperLongValue2'
}
$superLongVariableName = Get-MySuperLongVariablePlease -MySuperLongHashtableParameter $mySuperLongHashtableParameter -MySuperLongStringParameter '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' -Verbose
Bad:
Hashtable is not following Correct Format for Hashtables or Objects.
$superLongVariableName = Get-MySuperLongVariablePlease -MySuperLongHashtableParameter @{ MySuperLongKey1 = 'MySuperLongValue1'; MySuperLongKey2 = 'MySuperLongValue2' } -MySuperLongStringParameter '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' -Verbose
Bad:
Hashtable is not following Correct Format for Hashtables or Objects.
$superLongVariableName = Get-MySuperLongVariablePlease -MySuperLongHashtableParameter @{ MySuperLongKey1 = 'MySuperLongValue1'; MySuperLongKey2 = 'MySuperLongValue2' } `
-MySuperLongStringParameter '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' `
-Verbose
Bad:
Hashtable is not following Correct Format for Hashtables or Objects.
$superLongVariableName = Get-MySuperLongVariablePlease `
-MySuperLongHashtableParameter @{ MySuperLongKey1 = 'MySuperLongValue1'; MySuperLongKey2 = 'MySuperLongValue2' } `
-MySuperLongStringParameter '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' `
-Verbose
Bad:
Passing parameter (Verbose
) outside of the splat.
$getMySuperLongVariablePleaseParameters = @{
MySuperLongHashtableParameter = @{
MySuperLongKey1 = 'MySuperLongValue1'
MySuperLongKey2 = 'MySuperLongValue2'
}
MySuperLongStringParameter = '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
}
$superLongVariableName = Get-MySuperLongVariablePlease @getMySuperLongVariablePleaseParameters -Verbose
Good:
Get-ChildItem -Path C:\Documents -Filter *.md
Good:
$superLongVariableName = Get-MyVariablePlease -MyStringParameter '123456789012349012345678901234567890' -Verbose
Good:
$superLongVariableName = Get-MyVariablePlease -MyString1 '1234567890' -MyString2 '1234567890' -MyString3 '1234567890' -Verbose
Good:
$mySuperLongHashtableParameter = @{
MySuperLongKey1 = 'MySuperLongValue1'
MySuperLongKey2 = 'MySuperLongValue2'
}
$superLongVariableName = Get-MySuperLongVariablePlease -MySuperLongHashtableParameter $mySuperLongHashtableParameter -Verbose
Good:
Splatting all parameters.
$getMySuperLongVariablePleaseParameters = @{
MySuperLongHashtableParameter = @{
MySuperLongKey1 = 'MySuperLongValue1'
MySuperLongKey2 = 'MySuperLongValue2'
}
MySuperLongStringParameter = '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890'
Verbose = $true
}
$superLongVariableName = Get-MySuperLongVariablePlease @getMySuperLongVariablePleaseParameters
Good:
$superLongVariableName = Get-MySuperLongVariablePlease `
-MySuperLongHashtableParameter @{
MySuperLongKey1 = 'MySuperLongValue1'
MySuperLongKey2 = 'MySuperLongValue2'
} `
-MySuperLongStringParameter '123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890' `
-Verbose
Arrays should be written in one of the following formats.
If an array is declared on a single line, then there should be a single space between each element in the array. If arrays written on a single line tend to be long, please consider using one of the alternative ways of writing the array.
Bad:
Array elements are not format consistently.
$array = @( 'one', `
'two', `
'three'
)
Bad:
There are no single space beetween the elements in the array.
$array = @('one','two','three')
Bad:
There are multiple array elements on the same row.
$array = @(
'one', 'two', `
'my long string example', `
'three', 'four'
)
Bad:
Hashtable is not following Correct Format for Hashtables or Objects.
$array = @(
'one',
@{MyKey = 'MyValue'},
'three'
)
Bad:
Hashtables are not following Correct Format for Hashtables or Objects.
$myArray = @(
@{Key1 = Value1;Key2 = Value2},
@{Key1 = Value1;Key2 = Value2}
)
Good:
$array = @('one', 'two', 'three')
Good:
$array = @(
'one',
'two',
'three'
)
Good:
$array = @(
'one'
'two'
'three'
)
Good:
$hashtable = @{
Key = "Value"
}
$array = @( 'one', 'two', 'three', $hashtable )
Good:
$hashtable = @{
Key = "Value"
}
$array = @(
'one',
'two',
'three',
$hashtable
)
Good:
$myArray = @(
@{
Key1 = Value1
Key2 = Value2
},
@{
Key1 = Value1
Key2 = Value2
}
)
Hashtables and Objects should be written in the following format. Each property should be on its own line indented once. There should be no space between the brackets of an empty hashtable.
Bad:
$hashtable = @{
}
Bad:
$hashtable = @{Key1 = 'Value1';Key2 = 2;Key3 = '3'}
Bad:
$hashtable = @{ Key1 = 'Value1'
Key2 = 2
Key3 = '3' }
Good:
$hashtable = @{}
Good:
$hashtable = @{
Key1 = 'Value1'
Key2 = 2
Key3 = '3'
}
Good:
$hashtable = @{
Key1 = 'Value1'
Key2 = 2
Key3 = @{
Key3Key1 = 'ExampleText'
Key3Key2 = 42
}
}
Single quotes should always be used to delimit string literals wherever possible. Double quoted string literals may only be used when it contains ($) expressions that need to be evaluated.
Bad:
$string = "String that do not evaluate variable"
Bad:
$string = "String that evaluate variable {0}" -f $SomeObject.SomeProperty
Good:
$string = 'String that do not evaluate variable'
Good:
$string = 'String that evaluate variable {0}' -f $SomeObject.SomeProperty
Good:
$string = "String that evaluate variable $($SomeObject.SomeProperty)"
Good:
$string = 'String that evaluate variable ''{0}''' -f $SomeObject.SomeProperty
Good:
$string = "String that evaluate variable '{0}'" -f $SomeObject.SomeProperty
There should not be any commented-out code in checked-in files. The first letter of the comment should be capitalized.
Single line comments should be on their own line and start with a single pound-sign followed by a single space. The comment should be indented the same amount as the following line of code.
Comments that are more than one line should use the <# #>
format rather
than the single pound-sign. The opening and closing brackets should be on their
own lines. The comment inside the brackets should be indented once more than the
brackets. The brackets should be indented the same amount as the following line
of code.
Formatting help-comments for functions has a few more specific rules that can be found here.
Bad:
function Get-MyVariable
{#this is a bad comment
[CmdletBinding()]
param ()
#this is a bad comment
foreach ($example in $examples)
{
Write-Verbose -Message $example #this is a bad comment
}
}
Bad:
function Get-MyVariable
{
[CmdletBinding()]
param ()
# this is a bad comment
# On multiple lines
foreach ($example in $examples)
{
# No commented-out code!
# Write-Verbose -Message $example
}
}
Good:
function Get-MyVariable
{
# This is a good comment
[CmdletBinding()]
param ()
# This is a good comment
foreach ($example in $examples)
{
# This is a good comment
Write-Verbose -Message $example
}
}
Good:
function Get-MyVariable
{
[CmdletBinding()]
param ()
<#
This is a good comment
on multiple lines
#>
foreach ($example in $examples)
{
Write-Verbose -Message $example
}
}
PowerShell reserved Keywords should be in all lower case and should be immediately followed by a space if there is non-whitespace characters following (for example, an open brace).
Some reserved Keywords may also be followed by an open curly brace, for
example the catch
keyword. These keywords that are followed by a
curly brace should also follow the One Newline Before Braces
guideline.
The following is the current list of PowerShell reserved keywords in PowerShell 5.1:
begin, break, catch, class, continue, data, define do, dynamicparam, else,
elseif, end, enum, exit, filter, finally, for, foreach, from, function
hidden, if, in, inlinescript, param, process, return, static, switch,
throw, trap, try, until, using, var, while
This list may change in newer versions of PowerShell.
The latest list of PowerShell reserved keywords can also be found on this page.
Bad:
# Missing space after keyword and before open bracket
foreach($item in $list)
Bad:
# Capital letters in keyword
BEGIN
Bad:
# Violates 'One Newline Before Braces' guideline
begin {
# Do some work
}
Bad:
# Capital letters in 'in' and 'foreach' keyword
ForEach ($item In $list)
Good:
foreach ($item in $list)
Good:
begin
{
# Do some work
}