From noxfen-essentials
PowerShell scripting best practices for robust, maintainable scripts and modules. Activates when writing or reviewing .ps1/.psm1/.psd1 files, or when the user asks to "write a powershell script", "PS1 script", "powershell function", "pwsh", mentions PSScriptAnalyzer, or discusses PowerShell patterns. Covers both Windows PowerShell 5.1 and PowerShell 7+ (cross-platform).
How this skill is triggered — by the user, by Claude, or both
Slash command
/noxfen-essentials:powershell-best-practicesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Apply these rules whenever writing or reviewing PowerShell scripts.
Apply these rules whenever writing or reviewing PowerShell scripts.
Invoke-ScriptAnalyzer -Path script.ps1 -Severity Warning,Error
Install if missing: Install-Module PSScriptAnalyzer -Scope CurrentUser
#Requires -Version 5.1
[CmdletBinding()]
param(
[Parameter(Mandatory)]
[string]$InputPath,
[Parameter()]
[switch]$Force
)
$ErrorActionPreference = "Stop"
[CmdletBinding()] gives -Verbose, -Debug, -WhatIf for free$ErrorActionPreference = "Stop" — treat all errors as terminating#Requires — document minimum PS version explicitlyVerb-Noun with approved verbs (Get-Verb to list them)$PascalCase for module-level, $camelCase acceptable for local$script:MAX_RETRIES = 3 or Set-Variable -Option ReadOnlyGet-UserAccount not Get-UsrAcc)# try/catch for recoverable errors
try {
$result = Invoke-RestMethod -Uri $url -Method Get
} catch [System.Net.WebException] {
Write-Error "Network error: $_"
return $null
} catch {
throw # re-throw unexpected errors
}
# Use Write-Error not throw for non-fatal
# Use throw for fatal -- it terminates the call stack
Never use trap in modern PS — use try/catch/finally.
# Streams: use the right one
Write-Verbose "Processing file $path" # -Verbose flag controlled
Write-Debug "Internal state: $state" # -Debug flag controlled
Write-Warning "File missing, skipping" # yellow warning
Write-Error "Fatal: cannot continue" # error stream
Write-Output $result # pipeline output (or just: $result)
# Never Write-Host in functions/modules (breaks pipeline, no redirection)
# Write-Host OK only in interactive scripts/menus
# Explicit scope when needed
$script:Config = @{} # script scope
$global:Debug = $true # global (avoid)
# Splatting for long parameter lists
$params = @{
Path = $InputPath
Force = $Force
Verbose = $VerbosePreference -eq "Continue"
}
Copy-Item @params
# PS5.1: Set-Content -Encoding utf8 writes UTF-8 WITH BOM
# Fix: use .NET directly
[System.IO.File]::WriteAllText($path, $content, [System.Text.UTF8Encoding]::new($false))
# Pipeline chain operators (&&, ||) only in PS7+
# PS5.1: use if ($LASTEXITCODE -eq 0) { ... }
# $null comparison: put $null on LEFT
if ($null -eq $value) { ... } # correct
if ($value -eq $null) { ... } # wrong -- $value could be array
# String comparison is case-insensitive by default
if ($str -ceq "Exact") { ... } # -ceq for case-sensitive
function Get-ProcessedData {
[CmdletBinding()]
param(
[Parameter(Mandatory, ValueFromPipeline)]
[string]$InputData,
[ValidateSet("json", "csv", "xml")]
[string]$Format = "json"
)
process {
# process block for pipeline support
# ...
}
}
process {} block for pipeline-aware functions[ValidateSet], [ValidateRange], [ValidatePattern] for parameter validation<# .SYNOPSIS ... .PARAMETER ... .EXAMPLE ... #># Path separator
Join-Path $home "documents" "file.txt" # correct -- cross-platform
"$home\documents\file.txt" # wrong -- Windows only
# Detect OS
if ($IsWindows) { ... }
if ($IsLinux -or $IsMacOS) { ... }
# Use $PSScriptRoot not $MyInvocation.MyCommand.Path
$configPath = Join-Path $PSScriptRoot "config.json"
Get-Credential or SecretStoreInvoke-Expression — equivalent to eval in bash-ExecutionPolicy Bypass only in CI/installer scripts, never in production modules[ValidatePattern] or explicit checksnpx claudepluginhub noxfen/claude_skill_everywhere --plugin noxfen-essentialsCreates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.