PowerShell Style Guide
Apply the PoshCode PowerShell Practice and Style Guide when writing or reviewing PowerShell code.
Quick Reference - Essential Rules
Formatting
- OTBS braces: opening
{ on same line, closing } on own line
- 4-space indentation (spaces, not tabs)
- 115 char line limit - use splatting to break long commands
- No trailing whitespace, no semicolons as line terminators
- Two blank lines around function/class definitions
- Single space around operators and after commas
Naming
- PascalCase everything public: functions, parameters, variables, modules
- Verb-Noun for functions (approved verbs from
Get-Verb)
- Singular nouns only
- Full names always:
Get-Process -Name Explorer not gps Explorer
- lowercase for keywords (
if, foreach) and operators (-eq, -gt)
Function Structure
function Get-Example {
<#
.SYNOPSIS
Brief description.
.EXAMPLE
Get-Example -Name "Test"
Demonstrates basic usage.
#>
[CmdletBinding()]
[OutputType([string])]
param(
# The name to look up
[Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
[string]$Name
)
process {
# Return objects directly, no 'return' keyword
"Hello, $Name"
}
}
Key Patterns
- Always use
[CmdletBinding()]
- Always add
[OutputType()]
- Use
SupportsShouldProcess for state-changing commands
- Use parameter validation attributes (
[ValidateSet()], [ValidateRange()], etc.)
- Avoid
return keyword - output objects directly to pipeline
- Use
process {} block for pipeline input, not end {}
- Strongly type all parameters
- Use
[PSCredential] for credentials, never plain strings
Splatting Over Backticks
# Correct
$Params = @{
Path = $FilePath
Filter = "*.log"
Recurse = $true
ErrorAction = "Stop"
}
Get-ChildItem @Params
# Avoid backtick continuation
Get-ChildItem -Path $FilePath `
-Filter "*.log" `
-Recurse `
-ErrorAction Stop
Error Handling
try {
Do-Something -ErrorAction Stop
Do-More
} catch {
$err = $_
Write-Error "Failed: $($err.Exception.Message)"
}
Output Streams
| Command |
Purpose |
| Pipeline output |
Primary results (objects) |
Write-Verbose |
Status/logic details |
Write-Debug |
Debugging info for maintainers |
Write-Progress |
Real-time progress (ephemeral) |
Write-Warning |
Non-terminating warnings |
Write-Error |
Non-terminating errors |
Write-Host |
ONLY for Show-/Format- verbs or interactive prompts |
Review Checklist
When reviewing PowerShell code, check in priority order:
- Correctness: logic bugs, pipeline behavior, error handling
- Security: credential handling (PSCredential), input validation, injection risks
- CmdletBinding: present with OutputType, ShouldProcess where needed
- Naming: Verb-Noun, PascalCase, full names, approved verbs
- Formatting: OTBS braces, 4-space indent, line length, spaces around operators
- Documentation: comment-based help with Synopsis and Example
- Parameters: strongly typed, validation attributes, pipeline support
- Output: no Write-Host misuse, single type per command, raw data from tools
References
- Style details (capitalization, braces, whitespace, naming, comments, function structure): see references/style-guide.md
- Best practices (tool design, parameters, output, errors, performance, security): see references/best-practices.md
1---2name: powershell-style-guide3description: Review and write PowerShell code following community style guide and best practices (based on PoshCode/PowerShellPracticeAndStyle). Use when writing new PowerShell scripts, functions, or modules (.ps1, .psm1, .psd1), reviewing PowerShell code for style compliance, refactoring PowerShell code, or any task involving PowerShell scripting where code quality matters.4---56# PowerShell Style Guide78Apply the [PoshCode PowerShell Practice and Style Guide](https://github.com/PoshCode/PowerShellPracticeAndStyle) when writing or reviewing PowerShell code.910## Quick Reference - Essential Rules1112### Formatting1314- **OTBS braces**: opening `{` on same line, closing `}` on own line15- **4-space indentation** (spaces, not tabs)16- **115 char line limit** - use splatting to break long commands17- **No trailing whitespace**, no semicolons as line terminators18- **Two blank lines** around function/class definitions19- **Single space** around operators and after commas2021### Naming2223- **PascalCase** everything public: functions, parameters, variables, modules24- **Verb-Noun** for functions (approved verbs from `Get-Verb`)25- **Singular nouns** only26- **Full names** always: `Get-Process -Name Explorer` not `gps Explorer`27- **lowercase** for keywords (`if`, `foreach`) and operators (`-eq`, `-gt`)2829### Function Structure3031```powershell32function Get-Example {33 <#34 .SYNOPSIS35 Brief description.36 .EXAMPLE37 Get-Example -Name "Test"38 Demonstrates basic usage.39 #>40 [CmdletBinding()]41 [OutputType([string])]42 param(43 # The name to look up44 [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)]45 [string]$Name46 )47 process {48 # Return objects directly, no 'return' keyword49 "Hello, $Name"50 }51}52```5354### Key Patterns5556- Always use `[CmdletBinding()]`57- Always add `[OutputType()]`58- Use `SupportsShouldProcess` for state-changing commands59- Use parameter validation attributes (`[ValidateSet()]`, `[ValidateRange()]`, etc.)60- Avoid `return` keyword - output objects directly to pipeline61- Use `process {}` block for pipeline input, not `end {}`62- Strongly type all parameters63- Use `[PSCredential]` for credentials, never plain strings6465### Splatting Over Backticks6667```powershell68# Correct69$Params = @{70 Path = $FilePath71 Filter = "*.log"72 Recurse = $true73 ErrorAction = "Stop"74}75Get-ChildItem @Params7677# Avoid backtick continuation78Get-ChildItem -Path $FilePath `79 -Filter "*.log" `80 -Recurse `81 -ErrorAction Stop82```8384### Error Handling8586```powershell87try {88 Do-Something -ErrorAction Stop89 Do-More90} catch {91 $err = $_92 Write-Error "Failed: $($err.Exception.Message)"93}94```9596### Output Streams9798| Command | Purpose |99|---|---|100| Pipeline output | Primary results (objects) |101| `Write-Verbose` | Status/logic details |102| `Write-Debug` | Debugging info for maintainers |103| `Write-Progress` | Real-time progress (ephemeral) |104| `Write-Warning` | Non-terminating warnings |105| `Write-Error` | Non-terminating errors |106| `Write-Host` | ONLY for `Show-`/`Format-` verbs or interactive prompts |107108## Review Checklist109110When reviewing PowerShell code, check in priority order:1111121. **Correctness**: logic bugs, pipeline behavior, error handling1132. **Security**: credential handling (PSCredential), input validation, injection risks1143. **CmdletBinding**: present with OutputType, ShouldProcess where needed1154. **Naming**: Verb-Noun, PascalCase, full names, approved verbs1165. **Formatting**: OTBS braces, 4-space indent, line length, spaces around operators1176. **Documentation**: comment-based help with Synopsis and Example1187. **Parameters**: strongly typed, validation attributes, pipeline support1198. **Output**: no Write-Host misuse, single type per command, raw data from tools120121## References122123- **Style details** (capitalization, braces, whitespace, naming, comments, function structure): see [references/style-guide.md](references/style-guide.md)124- **Best practices** (tool design, parameters, output, errors, performance, security): see [references/best-practices.md](references/best-practices.md)