Troubleshooting
Scope: the errors and gotchas you'll actually hit, what they mean, and the plain fix for each. Verified against PowerShell 7.5.
Errors
"The term 'X' is not recognized"
Typo, missing module, or wrong shell. Fix: Get-Command *X*
to find it; Import-Module if it's installed but not loaded;
check you're in pwsh not powershell (5.1 lacks newer
commands).
"Cannot be loaded because running scripts is disabled"
Windows execution policy. Fix: Set-ExecutionPolicy
RemoteSigned -Scope CurrentUser (see
Installing PowerShell).
"Cannot bind parameter" / "Cannot convert value"
You passed the wrong type or shape: Get-Process -Name 123
works, but some parameters want specific types. Fix: read
the error — it names the parameter and expected type. Cast
explicitly: [int]$x = $input.
"You cannot call a method on a null-valued expression"
The PowerShell version of null-reference errors: something you
expected to exist is $null. Fix: check what's null
($var -eq $null), often a failed lookup or a typo'd property
name — verify with Get-Member.
try/catch didn't catch it
Non-terminating error. Fix: add -ErrorAction Stop to the
command, or set $ErrorActionPreference = "Stop". (See
Error Handling.)
"A positional parameter cannot be found"
You passed a value the command doesn't accept positionally.
Fix: name the parameter: Get-ChildItem -Path $p -Filter
*.log instead of guessing the order.
Gotchas (runs fine, surprises you)
= in an if is assignment
if ($x = 5) assigns and is always true. Fix: -eq.
Function output pollutes return values
A forgotten uncaptured command inside a function becomes part of
the result. Fix: assign or pipe to $null what you don't
mean to return; use Write-Host for progress text.
Format-* in the middle of a pipeline
... | Format-Table | Export-Csv exports formatting garbage,
not data. Fix: Format-* goes last, for eyes only.
Comparison is case-insensitive by default
"Ada" -eq "ada" is $true. Usually convenient, occasionally
surprising. Fix: -ceq when case matters.
$null on the wrong side
$null -eq $x is safe; $x -eq $null is usually fine too in
PowerShell (unlike some languages) — but $null on the left is
the habit that avoids collection-comparison surprises: @() -eq
$null behaves unexpectedly, $null -eq @() doesn't.
Aliases in scripts
?, %, select, sort are fine interactively but obscure in
scripts. Fix: full cmdlet names in anything saved
(Where-Object, ForEach-Object, Select-Object,
Sort-Object).
Windows paths with [brackets]
Remove-Item "file[1].txt" treats [1] as a wildcard pattern.
Fix: use -LiteralPath instead of -Path when filenames
contain [ ].
Debugging technique
$Error[0] | Format-List * -Force— the full error, every property.Set-PSDebug -Trace 1— line-by-line trace (like Bash-x);Set-PSDebug -Offto stop.Trace-Commandfor deep dives into specific subsystems.- Breakpoints:
Set-PSBreakpoint -Script .\s.ps1 -Line 10, then run — inspect variables at the prompt,continueto go on.
Check
- [ ] You read
$Error[0]in full before guessing - [ ] You write full cmdlet names in scripts, aliases only interactively
- [ ] You use
-LiteralPathfor filenames with brackets
Next: Glossary.