1---2name: powershell3description: Avoid common PowerShell mistakes — output behavior, array traps, and comparison operator gotchas.4---5
6## Output Behavior
7- Everything not captured goes to output — even without `return` or `Write-Output`
8- `return` doesn't stop output — previous uncaptured expressions still output
9- `Write-Host` bypasses pipeline — use for display only, not data
10- Assign to `$null` to suppress — `$null = SomeFunction`
11- `[void]` cast also suppresses — `[void](SomeFunction)`
12
13## Array Gotchas
14- Single item result is scalar, not array — `@(Get-Item .)` forces array
15- Empty result is `$null`, not empty array — check with `if ($result)` carefully
16- Array unrolling in pipeline — `@(1,2,3) | ForEach` sends items one by one
17- `+=` on array creates new array — slow in loops, use `[System.Collections.ArrayList]`
18- `,` is array operator — `,$item` wraps single item in array
19
20## Comparison Operators
21- `-eq`, `-ne`, `-gt`, `-lt` — not `==`, `!=`, `>`, `<`
22- `-like` with wildcards, `-match` with regex — both return bool
23- `-contains` for array membership — `$arr -contains $item`, not `$item -in $arr` (though `-in` works too)
24- Case-insensitive by default — `-ceq`, `-cmatch` for case-sensitive
25- `$null` on left side — `$null -eq $var` prevents array comparison issues
26
27## String Handling
28- Double quotes interpolate — `"Hello $name"` expands variable
29- Single quotes literal — `'$name'` stays as literal text
30- Subexpression for complex — `"Count: $($arr.Count)"` for properties/methods
31- Here-strings for multiline — `@" ... "@` or `@' ... '@`
32- Backtick escapes — `` `n `` for newline, `` `t `` for tab
33
34## Pipeline
35- `$_` or `$PSItem` is current object — same thing, `$_` more common
36- `ForEach-Object` for pipeline — `foreach` statement doesn't take pipeline
37- `-PipelineVariable` saves intermediate — `Get-Service -PV svc | Where ...`
38- Pipeline processes one at a time — unless function doesn't support streaming
39
40## Error Handling
41- `$ErrorActionPreference` sets default — `Stop`, `Continue`, `SilentlyContinue`
42- `-ErrorAction Stop` per command — makes non-terminating errors terminating
43- `try/catch` only catches terminating — set `ErrorAction Stop` first
44- `$?` is last command success — `$LASTEXITCODE` for native commands
45
46## Common Mistakes
47- No space before `{` in `if` — `if($x){` works but `if ($x) {` preferred
48- `=` is assignment in conditions — use `-eq` for comparison
49- Function return array unrolls — `return ,@($arr)` to keep array
50- `Get-Content` returns lines array — `-Raw` for single string
51- `Select-Object` creates new object — properties are copies, not references
52
53## Cross-Platform
54- `pwsh` is PowerShell 7+ — `powershell` is Windows PowerShell 5.1
55- Paths use `/` or `\` — `Join-Path` for portable
56- Environment vars: `$env:VAR` — works on all platforms
57- Aliases differ across platforms — `ls`, `cat` may not exist, use full cmdlet names