When a newcomer to PowerShell begins to write scripts, they typically focus on the code. After all, the code is what makes things happen! Executable code is obviously important, but what happens when you write so much code, you forget what it does?

If you're on a team, do they understand the code you're writing? PowerShell comments can help.

Writing descriptive and informative PowerShell comments in scripts helps us humans understand the intention of the code, the result, and perhaps describes edge cases that were encountered at one time.

In this article, you're going to learn about the different types of comments in PowerShell, which ones to use and how to use them effectively in your scripts.

Using Single-Line Comments

Have you ever written some code and had to review it weeks or months later? Probably. Did you understand it that much later? Maybe not. If only you left some useful comments in your code!

Most programming languages have a concept of commenting. PowerShell is no exception. In PowerShell, your friend is #. Everything that follows the hashtag (#) in the same line is ignored by PowerShell as interpreted code.

The example code below is an excerpt from a script that... well, you can refer to the PowerShell script comment on the first line to know what it does. If you're a PowerShell expert, you can probably point out what this snippet does without the comment.

#Get all files with TXT extension, show the name of each file and then delete them.
Get-ChildItem *.TXT | ForEach-Object {
    Write-Output $_.FullName
    Remove-Item $_.FullName
}

But, how about when you encounter a terse command like this one below?

"{0},{1}" -f [bool](gm -input (1..20) -name count), (1..20).count

Adding comments will do you or anyone who will eventually read your code a great service. As you can see below, adding a comment above the terse command makes a lot of difference in understanding the code.

#Check whether the object has a property named "count". Then, return true or false.
"{0},{1}" -f [bool](gm -input (1..20) -name count), (1..20).count

Using Block Comments / Multiline Comments

In the previous section, you learned that a comment starts with a # character. There's no stopping you from creating multiple lines of comments. In fact, before PowerShell 2.0, the only way to create multiline comments is to create multiple lines of single-line comments.

It's good to keep comments brief and concise, but some scenarios call for using a PowerShell multiline comment, which can also be referred to as a PowerShell comment block.

A comment block in PowerShell starts with <# and ends with #>. Below are some examples of when a comment block is applicable.

Splitting a Long Comment into Multiple Lines

It is sometimes unavoidable to have a long comment in a script. These long comments can go way beyond your current frame of the display. When that happens, you will need to keep on scrolling horizontally to read the entire comment line.

For example, instead of having a long single-line comment such as:

# It is sometimes unavoidable to have a long comment in a script. These long comments can go way beyond your current frame of the display. And when that happens, you will need to keep on scrolling horizontally to read the entire comment line.

Why not turn it into a multiline comment that's easier to read like this one below:

<#
It is sometimes unavoidable to have a long comment in a script.
These long comments can go way beyond your current frame of the display.
And when that happens, you will need to keep on scrolling horizontally
to read the entire comment line.
#>

Adding Descriptive Text

Have you ever downloaded or written a script, saved it under some random  or non-descriptive name? I know I have!

When you open the script to find out what the heck it is, it sure would be nice if there are useful details listed inside like what the script is for like who created it and when was it created.

A block comment in PowerShell is useful for adding descriptive text in your scripts. This way, the purpose of the script is already given and is also a great way to include warnings or things to watch out for when using the script.

Below is an example of a block comment describing what the script is, when it was last updated and also shows a warning of what not to do when running the script.

<#
Using this script will export the email addresses of all mailboxes
in the Exchange organization.

WARNING: DO NOT RUN THIS SCRIPT IN THE EXCHANGE MANAGEMENT SHELL.

Last update: Feb 16, 2020
#>

Documenting Requirements and Steps

If your script has a specific way to execute, or have special requirements to run, block comments would help in documenting it inside your script or function.

Below is an example of documenting a requirement and steps using block comments.

<#
This function requires an encrypted credential XML file that will be used
to authenticate with Office 365.

If you don't have this yet, follow these steps.

1. Open PowerShell
2. Run this command - 'Get-Credential | Export-CliXml .\\credential.XML'
3. Make sure to save the XML file inside the same folder as the script.

NOTE: The credential XML file will only work on the same computer and the same account
used to generate it.
#>

Commenting Out Existing Code

Comments are used not just for the purpose of adding comments. You can also turn existing lines of code into single-line or block comments.

Perhaps you find yourself testing or debugging scripts. When code is commented out, PowerShell skips that code from executing during runtime.

For example, you have a script that gets a list of users in Active Directory, and that list is processed using the foreach loop to set each user's department name using the Set-AdUser cmdlet.

<#
This script will get all AD users matching the filter
and each user's department name will be changed to 'Finance'.
#>
$adUsers = Get-ADUser -Filter *
foreach ($user in $adUsers) {
    Write-Output "$($user.Name) - Department name will be chaged to 'Finance'"
    Set-AdUser -Identity ($user.SamAccountName) -Department 'Finance'
}

But if you want to test the foreach loop without running the Set-AdUser line yet, then you just need to comment-out that particular line like so:

foreach ($user in $adUsers) {
    Write-Output "$($user.Name) - Department name will be chaged to 'Finance'"
    #Set-AdUser -Identity ($user.SamAccountName) -Department 'Finance'
}

Now the script can be safely tested without actually changing the department name of each user.

TIP: In Visual Studio Code, you can comment out a line or multiple lines by pressing the "CTRL + /" keyboard shortcut.
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/73fdb20f-c41b-4f19-a9a3-c3255add0693/vscode-comment-single-01.gif
Single-line commenting shortcut in Visual Studio Code

Now, if you want to comment out multiple lines, you have a choice of either putting a # at the beginning of each line, or you can enclose multiple lines inside the <# #> block like shown in the example below.  As you can see, the entire foreach loop has been turned into a block comment.

$adUsers = Get-ADUser -Filter *
<# foreach ($user in $adUsers) {
    Write-Output "$($user.Name) - Department name will be changed to 'Finance'"
    Set-AdUser -Identity ($user.SamAccountName) -Department 'Finance'
} #>
TIP: In Visual Studio Code, you can also create a comment block by highlighting a line or multiple lines of code and pressing the "ALT +SHIFT + A" keyboard shortcut.
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/a9e7077a-4178-493f-9740-fc5a68f8e31e/vscode-comment-multi.gif
Block commenting shortcut in Visual Studio Code

Comment-Based Help

When you want to make your scripts or functions to look more professional, you can make it so by adding comment-based help. A comment-based help is a collection of keywords and texts enclosed in a block comment.

Visit the page - About Comment Based Help - to learn more about the Comment-Based Help keyword and syntax.

The sample code below demonstrates a script named Get-WhatTimeIsItNow.ps1, having a comment-based help included.

<#
.SYNOPSIS
    Short description of the script
.DESCRIPTION
    Long description of the script
.EXAMPLE
    PS C:\\> Get-WhatTimeIsItNow.ps1
    Explanation of what the example does
.INPUTS
    Inputs (if any)
.OUTPUTS
    Output (if any)
.NOTES
    General notes
#>

Get-Date -Format t

Comment-based enables Get-Help support for your scripts. This means that when you run Get-Help <script/function>, PowerShell will return the 'help' text contained in your script like the one shown below.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/394f3a5d-cd03-4cc6-a694-7c4bd346d260/get-help1.gif
Get-Help output for scripts with comment-based help
TIP: In Visual Studio Code, you can insert a default comment-based help block by typing in comment-help in the editor pane.
https://s3-us-west-2.amazonaws.com/secure.notion-static.com/555a4c6f-9292-4046-94da-fd81df525115/add-comment-help.gif
Inserting a default comment-based help block in Visual Studio Code

Best Practices

Here are some of what you may call best practices for creating effective comments. These are not in any way hard requirements but are recommendations that many already put into practice that you can use as a guide.

Do not refer to line numbers in your comments

When writing code, you might be tempted to add a reference to a line number in your comments. You may be right in thinking that adding line number references makes your code that much easier to understand. That is if you're sure that your code will never be modified.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6092bdd1-2215-4844-ab8b-763a9f091db3/Untitled.png
Comment with line number reference

Imagine that a new line of code is inserted into your script. This would mean that all the line number references in your comments already got shifted. And to keep the line numbering accurate, you will have to edit the comments to update them one by one.

Do not add comments after the script

We, humans, are used to reading from top to bottom. If the comment you are adding is important for the succeeding lines of codes, then it is only logical to add the comments before.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/6b7fdc16-2762-4e68-829c-1ce18e148429/Untitled.png
Right and Wrong comment placement

After all, if you are adding comments in the script about the script, isn't it more sensible to have the comments before the code and not after?

Do not add comments at the end of a line

Same as the previous example, putting comments after the code, even if it is on the same line, is no better than placing the comment below the code.

Adding comments at the end of the code can cause editing errors because instead of being focused on modifying the code, you'd also have to mind that the comment moves along as the code changes.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/fafafae4-760b-4ec9-9847-2f6c1ed3f2ca/Untitled.png
A comment is added to the end of the code

Do not state the obvious

Sometimes the code is just too simple and the intent is already too obvious that adding a comment to it is just a waste. Generally in this situation, a comment could be even longer than the code that it refers to.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/2ac7526a-10df-4655-a6da-4a832647fc29/Untitled.png
An obvious command with a comment.

If you believe that the code is self-explanatory, you may want to consider skipping adding a comment.

Summary

In this article, you've learned the importance of adding comments to your PowerShell scripts or functions. You also learned the different types of comments available and how a properly crafted and placed comment can significantly increase the readability of your code.

There are no hard and fast rules on how to apply comments in PowerShell, but there are tested and proven recommendations on how to use them. In the end, it is up to you how you want to use comments in your scripts to remind you of the crucial things from beginning to end.

Further Reading