Skip to content

PowerShell Comments

How to use single-line (#) and block (<# #>) comments in PowerShell scripts, including best practices for inline documentation and comment-based help.

Comments are non-executable text annotations embedded in source code that the PowerShell parser ignores during script execution. They are used to document logic, explain complex operations, and provide structured metadata for PowerShell's built-in help engine.

Single-Line Comments (#)

A single-line comment begins with the hash symbol (#) and extends to the end of that physical line. Any text following the # is discarded by the parser.

Single-line comments can stand alone on their own line or be placed after a statement as an inline annotation.

single-line-comments.ps1powershell
$LogDirectory = "C:\Logs\Archived"

if (-not (Test-Path -Path $LogDirectory)) {
    New-Item -ItemType Directory -Path $LogDirectory | Out-Null # Suppress pipeline output
}

Write-Output "Hello, PowerShell!"
Write-Output "Log storage initialized at: $LogDirectory"

where:

  • # This script initializes... is a full-line comment describing the script's purpose.
  • # Suppress pipeline output is an inline comment, placed after a valid statement on the same line.

Run the script from the console:

Consolepowershell
pwsh ./single-line-comments.ps1
Outputplaintext
Hello, PowerShell!
Log storage initialized at: C:\Logs\Archived

Block Comments (<# #>)

A block comment spans multiple lines. It begins with <# and ends with #>. Everything between these markers is ignored, regardless of line breaks.

Block comments are commonly used to write lengthy design notes or temporarily disable sections of executable code during troubleshooting.

block-comments.ps1powershell
<#
    Script: archive-logs.ps1
    Author: Systems Engineering Team
    Purpose: Compresses and moves operational event logs
             to secondary backup volumes.
#>

$TargetFolder = "C:\AppLogs"

<#
$LegacyBackupPath = "D:\OldBackups"
Write-Warning "Legacy backup path is deprecated."
#>

Write-Output "Active archive target: $TargetFolder"

where:

  • <# ... #> at the top forms a multi-line documentation block.
  • The second block comment comments out legacy code so the engine skips its execution.

Run the script from the console:

Consolepowershell
pwsh ./block-comments.ps1
Outputplaintext
Active archive target: C:\AppLogs

Comment-Based Help

PowerShell includes a documentation framework called Comment-Based Help. By structuring a block comment using recognized uppercase tags, PowerShell automatically compiles and exposes native documentation for your scripts and functions via the Get-Help cmdlet.

Valid Placement Rules

For a standalone .ps1 script, the comment-based help block must be placed in one of three locations:

  1. At the very beginning of the script file.
  2. Directly after the opening param(...) block.
  3. At the very end of the script file.

For functions, the block must be placed directly above the function statement or inside the opening curly brace { of the function body.

Common Comment-Based Help Keywords

Keyword Purpose
.SYNOPSIS A brief, one-line summary of the command.
.DESCRIPTION A detailed explanation of what the command does.
.PARAMETER <Name> Describes an individual parameter. Use one block per parameter.
.EXAMPLE Shows a sample invocation, optionally with explanatory text.
.OUTPUTS The .NET types or object formats emitted by the command.
.NOTES Additional information, such as author, version history, or prerequisites.
.LINK A related URL or another command name for cross-reference.

Practical Example: Implementing Comment-Based Help

The following script queries logical drives and includes a complete Comment-Based Help block.

Get-DiskReport.ps1powershell
<#
.SYNOPSIS
    Queries logical storage drives and reports available capacity.

.DESCRIPTION
    Get-DiskReport uses CIM instances to discover fixed logical disk drives
    on the current host, calculating both free and total gigabytes.

.PARAMETER DriveType
    The numeric drive type to target (e.g., 3 for Fixed Hard Disks).
    Defaults to 3.

.EXAMPLE
    .\Get-DiskReport.ps1 -DriveType 3
    Returns capacity statistics for all local fixed hard drives.

.OUTPUTS
    System.Management.Automation.PSCustomObject

.NOTES
    Author: Tutorial Reference
    Date: 2026-09-22
#>

param (
    [int]$DriveType = 3
)

Get-CimInstance -ClassName Win32_LogicalDisk -Filter "DriveType=$DriveType" |
    ForEach-Object {
        [PSCustomObject]@{
            DeviceID    = $_.DeviceID
            TotalSizeGB = [math]::Round($_.Size / 1GB, 2)
            FreeSpaceGB = [math]::Round($_.FreeSpace / 1GB, 2)
        }
    }

where:

  • The <# ... #> block specifies standard tags parsed by the help system.
  • param ([int]$DriveType = 3) exposes a configurable parameter linked to .PARAMETER DriveType.
  • Get-CimInstance queries the system's storage state.

Query your custom script using the built-in Get-Help engine:

Consolepowershell
Get-Help .\Get-DiskReport.ps1 -Full
Outputplaintext
NAME
    C:\Users\Tom\Desktop\script.ps1

SYNOPSIS
    Queries logical storage drives and reports available capacity.


SYNTAX
    C:\Users\Tom\Desktop\script.ps1 [[-DriveType] <Int32>] [<CommonParameters>]


DESCRIPTION
    Get-DiskReport uses CIM instances to discover fixed logical disk drives
    on the current host, calculating both free and total gigabytes.


PARAMETERS
    -DriveType <Int32>
        The numeric drive type to target (e.g., 3 for Fixed Hard Disks).
        Defaults to 3.

        Required?                    false
        Position?                    1
        Default value                3
        Accept pipeline input?       false
        Accept wildcard characters?  false

    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see
        about_CommonParameters (https:/go.microsoft.com/fwlink/?LinkID=113216).

INPUTS

OUTPUTS
    System.Management.Automation.PSCustomObject


NOTES


        Author: Tutorial Reference
        Date: 2026-09-22

    -------------------------- EXAMPLE 1 --------------------------

    PS C:\>.\Get-DiskReport.ps1 -DriveType 3

    Returns capacity statistics for all local fixed hard drives.





RELATED LINKS

Best Practices for Documenting Scripts

  • Prioritize self-documenting code. Choose descriptive variable names such as $ProcessTimeoutSeconds instead of $t, and use standard Verb-Noun function names. Good code minimizes the need for excessive inline comments.
  • Explain "why," not just "what". Code often shows what is happening; comments should clarify why a particular approach was chosen.
    • Avoid redundant comments:
      $count = $count + 1
    • Document rationale, edge cases, and constraints:
      Start-Sleep -Seconds 15
  • Keep comments up to date. An outdated comment is worse than no comment, so always update comments when you change the logic they describe.
  • Use comment-based help for shared scripts and functions. Any script or function intended for reuse by others, or by your future self, should include at least .SYNOPSIS, .DESCRIPTION, .PARAMETER, and one .EXAMPLE.
  • Avoid excessive inline commenting. Commenting every single line adds noise; reserve comments for non-obvious logic, workarounds, or important context.
  • Remove dead code instead of commenting it out. Avoid accumulating large blocks of commented-out code in production scripts. Track historical iterations using version control systems like Git.
  • Document complex regular expressions. When using advanced patterns with -match or -replace, include an inline comment explaining what the pattern captures and matches.
  • Use block comments for temporary disabling, not permanent documentation. Long-term documentation belongs in comment-based help or a README, not scattered <# #> blocks throughout the script body.
Navigation