Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions src/docs/Coding-Standards/PowerShell/Messaging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
---
title: Messaging
description: "Write-Verbose for user-facing operational progress and normal troubleshooting; Write-Debug for developer-focused internals and deep diagnostics."
---

# Messaging

Choose between `Write-Verbose` and `Write-Debug` based on the audience and purpose of the message. This distinction clarifies intent for maintainers, improves discoverability for operators, and keeps diagnostic output focused.

## The rule

- **Use `Write-Verbose`** for **user-facing** operational progress, decision summaries, and normal troubleshooting context β€” information that helps operators understand execution flow and diagnose issues at the normal operational level.
- **Use `Write-Debug`** for **developer-focused** internals, deep diagnostics, low-level payload and transport details, internal state, and instrumentation β€” information for the author and maintainers of the code, not operators.

## Examples

### Write-Verbose: operational progress and troubleshooting

These messages help an operator understand *what is happening* and *why*, without needing to know the implementation details.

```powershell
# Progress narration β€” what step is running
Write-Verbose "Retrieving repository metadata from GitHub..."

# Decision summary β€” what the code decided and why
Write-Verbose "Found 3 matching repositories; filtering to 1 owned by the org"

# Outcome β€” what succeeded or failed at the user-visible level
Write-Verbose "Successfully cloned repository to $DestinationPath"

# Configuration recap β€” what settings are in use
Write-Verbose "Using authentication method: Personal Access Token"
```

Verbose messages stay at a **business level**: they talk about repositories, deployments, workflows, API calls β€” things an operator cares about.

### Write-Debug: internals and deep diagnostics

These messages are for the code author and maintainers. They expose the implementation details that help diagnose why something went wrong *internally*.

```powershell
# Payload details β€” the raw data moving through the code
Write-Debug "Request body: $($RequestBody | ConvertTo-Json -Depth 10)"

# Internal state β€” variables and computed values
Write-Debug "Resolved repository ID to: $RepoID"
Write-Debug "Cache hit: $CacheHit; items in cache: $($Cache.Count)"

# Low-level transport details β€” HTTP headers, raw responses
Write-Debug "Response header 'X-RateLimit-Remaining': $($Response.Headers['X-RateLimit-Remaining'])"

# Instrumentation β€” timing, counters, flow paths
Write-Debug "Processed $ProcessedCount of $TotalCount items (elapsed: $ElapsedMs ms)"
Write-Debug "Taking fallback branch: condition was $Condition"
```

Debug messages expose **plumbing**: they talk about payloads, headers, cache state, internal variables β€” details that only make sense in the context of reading the code.

## Review checklist

When writing messages, ask:

1. **Is this message useful at normal troubleshooting level?** βœ“ Use `Write-Verbose`
- Operators should understand it without reading source code.
- It describes *what* is happening at the business level (workflow, deployment, repository, API call).
- It helps answer "what did my operation do?" or "where did it fail?".

2. **Is this an internal/deep diagnostic detail?** βœ“ Use `Write-Debug`
- Only a code author or maintainer needs this information.
- It exposes implementation details (payload, headers, internal variables, timing).
- It helps answer "why did the code take this path?" or "what is the state inside this function?".

3. **Am I unsure?** Prefer `Write-Verbose` β€” it's safer to be slightly more verbose at the normal level than to hide troubleshooting context that operators need.

## Enabling messages at runtime

PowerShell controls visibility with built-in preference variables β€” no code change needed to see messages:

- **Show verbose messages:** run the command with the `-Verbose` switch, or set `$VerbosePreference = 'Continue'` before calling.
- **Show debug messages:** set `$DebugPreference = 'Continue'` before calling the command (no `-Debug` switch exists; use the preference).

Example:

```powershell
# Operator runs the command with -Verbose to see operational context
Get-Repository -Owner 'MyOrg' -Name 'MyRepo' -Verbose

# Or sets the preference for all calls in the session
$VerbosePreference = 'Continue'
Get-Repository -Owner 'MyOrg' -Name 'MyRepo'

# In a script, enable debug messages
$DebugPreference = 'Continue'
Invoke-RepositoryOperation
```

## Relationship to other messaging

This standard covers the two main diagnostic channels. For context:

- **`Write-Information`** β€” user-facing but outside the troubleshooting spectrum. Use it for important operational summaries that should always be visible (not gated by `-Verbose`), e.g., "Migration complete: 42 items processed."
- **`Write-Warning`** β€” a condition the operator should know about but that did not stop the operation; reserved for genuine warnings, not verbose narration.
- **`Write-Error`** (terminating) β€” a failure that stops execution; emit structured errors with `[PSCustomObject]` or `-ErrorRecord` for discoverability.
- **Logging (event logs, files)** β€” persistent audit; separate from these streams and outside the scope of this standard.

Reserve the verbose and debug streams for their intended audiences, and keep messages at the right level so operators and maintainers can both find what they need.
1 change: 1 addition & 0 deletions src/docs/Coding-Standards/PowerShell/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This standard builds on the [language-agnostic baseline](../index.md); where the
| [Functions](Functions.md) | Advanced functions β€” CmdletBinding, typed and validated parameters, pipeline blocks, ShouldProcess, and required comment-based help. |
| [Classes](Classes.md) | When to reach for a PowerShell class, and how to structure its members, constructors, and documentation. |
| [Scripts](Scripts.md) | Structure for standalone .ps1 scripts β€” requirements, parameters, help, and keeping the script thin. |
| [Messaging](Messaging.md) | Write-Verbose for user-facing operational progress and normal troubleshooting; Write-Debug for developer-focused internals and deep diagnostics. |
| [Version Constraints](Version-Constraints.md) | Express module and package version constraints as NuGet version ranges β€” the canonical notation across PSResourceGet, .NET package references, and (mapped) #Requires and module manifests. |
| [Module Requirements](Requires-Modules.md) | Valid `#Requires -Modules` version specifications β€” minimum, major-lock (with the `N.*` wildcard), exact, and GUID identity pinning β€” with an executable proof. |

Expand Down
1 change: 1 addition & 0 deletions src/zensical.toml
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ nav = [
{"Functions" = "Coding-Standards/PowerShell/Functions.md"},
{"Classes" = "Coding-Standards/PowerShell/Classes.md"},
{"Scripts" = "Coding-Standards/PowerShell/Scripts.md"},
{"Messaging" = "Coding-Standards/PowerShell/Messaging.md"},
{"Version Constraints" = "Coding-Standards/PowerShell/Version-Constraints.md"},
]},
{"Terraform" = "Coding-Standards/Terraform.md"},
Expand Down