You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/Markdown.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -54,3 +54,12 @@ These rules are disabled or widened so they do not flag valid documentation —
54
54
-**Surround headings, lists, and fenced blocks with a blank line** for readability, even though the linter no longer enforces it.
55
55
-**Prefer relative links** within a repository; use the canonical published URL for cross-repository references.
56
56
-**Tag every code fence with a language** (` ```bash `, ` ```yaml `) so it is highlighted and converts cleanly when published.
57
+
58
+
## PowerShell code samples
59
+
60
+
Documentation is full of PowerShell, so present it the way the [PowerShell standard](PowerShell/index.md) writes it:
61
+
62
+
-**Label the fence `powershell`**, and put command output in a separate block labelled `Output`, so it is neither highlighted as code nor mistaken for input.
63
+
-**Use full cmdlet and parameter names**, and avoid positional parameters, so a reader can copy the sample and run it.
64
+
-**Avoid backtick line-continuation.** Break a long call with splatting, or at PowerShell's natural points — after a pipe, an opening parenthesis, or a brace.
65
+
-**Leave out the prompt string** (`PS>`) unless the sample is specifically about interactive, prompt-changing behaviour.
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/PowerShell/Functions.md
+15-1Lines changed: 15 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -66,7 +66,21 @@ function Get-UserData {
66
66
## Errors and output
67
67
68
68
-**`throw` for terminating errors**; `Write-Error` only where the caller is expected to handle a non-terminating one.
69
-
-**Emit one object type**, matching `[OutputType()]`; never `Write-Host` data another command might consume.
69
+
-**Call cmdlets you mean to trap with `-ErrorAction Stop`** so they raise terminating, catchable errors, and set `$ErrorActionPreference = 'Stop'` around native commands, restoring it afterward.
70
+
-**Put the whole transaction in the `try` block** rather than setting success flags to gate later code, and do not lean on `$?` — it reports only whether the last command considered itself successful, with no detail.
71
+
-**In a `catch`, copy `$_` into your own variable first**, before later commands overwrite it. The baseline rules — fail fast, never swallow — live in [Error Handling](../Error-Handling.md).
72
+
73
+
## Output streams
74
+
75
+
Send each kind of message to the stream built for it, so a caller can capture, redirect, or silence it:
76
+
77
+
-**Results** are objects on the output stream — emit them implicitly by naming the object on its own line; do **not** use `return $obj` to emit, and in a pipeline function emit from `process`, not `end`.
78
+
-**Emit one object type**, matching `[OutputType()]`.
79
+
-**`Write-Verbose`** for status a caller may want (`-Verbose`), **`Write-Debug`** for maintainer breadcrumbs (`-Debug`), and **`Write-Progress`** for progress that need not persist.
80
+
-**`Write-Warning`** and **`Write-Error`** for warnings and non-terminating errors.
81
+
-**`Write-Host`** only for `Show-` or `Format-` verbs or an interactive prompt — never for data another command might consume.
82
+
83
+
`[CmdletBinding()]` is what turns on the `-Verbose` and `-Debug` switches, so those streams reach the caller.
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/PowerShell/Scripts.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -48,3 +48,8 @@ $ErrorActionPreference = 'Stop'
48
48
-**Name scripts `Verb-Noun.ps1`** to match the function convention.
49
49
-**No side effects on load.** A script runs top to bottom when invoked; it should not do work merely by being dot-sourced.
50
50
-**Return objects**, so the script composes in a pipeline like any other command.
51
+
52
+
## Paths
53
+
54
+
-**Do not depend on the current directory.** Avoid relative paths and `~` — the meaning of `~` depends on the current PowerShell provider — and build paths from `$PSScriptRoot` with `Join-Path`.
55
+
-**Pass full paths to .NET and native calls.** .NET methods and external executables read `[System.Environment]::CurrentDirectory`, which PowerShell does not keep in step with `$PWD`, so a relative path resolves against the wrong place. Resolve to a full path first.
Copy file name to clipboardExpand all lines: src/docs/Coding-Standards/PowerShell/index.md
+11-1Lines changed: 11 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -19,13 +19,23 @@ This standard builds on the [language-agnostic baseline](../index.md); where the
19
19
20
20
<!-- INDEX:END -->
21
21
22
+
## Tools and controllers
23
+
24
+
PowerShell falls into two kinds, and the difference decides how a command shapes its output:
25
+
26
+
- A **tool** is a reusable unit — an advanced function, usually exported from a module. It takes input only through parameters and emits **raw, least-manipulated objects**, so it stays usable in situations its author never imagined; a tool that measures a size returns bytes, not a rounded string.
27
+
- A **controller** is a script that automates one process by calling tools. It may reshape, round, or format data for how it will be read, and it is not meant to be reused.
28
+
29
+
Keep the shaping at the edge: tools stay general and emit raw objects, and a controller — or a format view (`.format.ps1xml`) — turns those into presentation. This is the [thin script](Scripts.md) rule seen from the other side, and it is why tools [emit objects, not text](#shared-conventions).
30
+
22
31
## Shared conventions
23
32
24
33
These hold for all PowerShell, whatever the construct:
25
34
26
35
-**`Verb-Noun` naming** with an approved verb (`Get-Verb`) and a singular noun: `Get-RepositorySecret`, not `Fetch-Secrets`.
27
36
-**`PascalCase`** for functions, parameters, public variables, and class members; `camelCase` for local variables.
28
37
-**Full cmdlet names, never aliases** (`Where-Object`, not `?`; `ForEach-Object`, not `%`).
38
+
-**Full parameter names, and standard ones.** Pass parameters by name and avoid positional arguments in shared code — `Get-Process -Name pwsh`, not `Get-Process pwsh` — so a call survives parameter-set changes and reads clearly. Name your own parameters after PowerShell's built-ins (`Path`, `Name`, `ComputerName`), not `$Param_Computer`.
29
39
-**Set `$ErrorActionPreference = 'Stop'`** at the top of every script and module so errors are terminating, not silently swallowed.
30
40
-**Emit objects, not formatted text.** Return rich objects and let the caller format; reserve `Write-Host` for genuine console UX, and use `Write-Verbose` / `Write-Information` for progress narration.
31
41
@@ -49,7 +59,7 @@ Beyond the basics, these language-specific habits keep PowerShell correct and fa
49
59
-**Put `$null` on the left of a comparison** — `$null -eq $x`, never `$x -eq $null`. Against a collection the right-hand form *filters* rather than tests. Use `-contains` / `-in` for membership, never `-eq`.
50
60
-**Suppress unwanted output with `$null = ...`** (or `[void]` for method calls), not `| Out-Null` — the pipeline form is markedly slower on hot paths.
51
61
-**Build collections with a typed list, not `+=` in a loop.**`$a += $x` reallocates the whole array every iteration; use `[System.Collections.Generic.List[T]]` with `.Add()`, and prefer a cmdlet's `-Filter` over piping to `Where-Object` on large sets.
52
-
-**Keep secrets out of source, and never `Invoke-Expression` untrusted input.**Take secrets as `[securestring]`or through `Get-Credential`, and guard state-changing commands with `ShouldProcess` (see [Functions](Functions.md)); the wider rules live in the [Security](../Security.md) baseline.
62
+
-**Keep secrets out of source, and never `Invoke-Expression` untrusted input.**Accept credentials as a `[PSCredential]`parameter with the `[Credential()]` attribute rather than calling `Get-Credential` inside a reusable function, so a caller can pass one they already hold, and take other sensitive values as `[securestring]`. Guard state-changing commands with `ShouldProcess` (see [Functions](Functions.md)); the wider rules live in the [Security](../Security.md) baseline.
0 commit comments