# Windows Powershell Safety

> Use when driving PowerShell on this machine — before trusting a failed exit status, before combining a heredoc with a deletion in one call, or when writing a file another tool will parse.

- Skill: `presidenteog/windows-powershell-safety` (Agent Skill)
- Install (CLI): `npx skillmds@latest add presidenteog/windows-powershell-safety`
- Raw SKILL.md: https://api.skillmd.com/api/skills/presidenteog/windows-powershell-safety/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: PresidenteOG (https://skillmd.com/u/presidenteog)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/presidenteog/windows-powershell-safety

---


# Windows PowerShell safety

Four ways a PowerShell call on this machine reports something other than the truth,
even though nothing here is exotic — all found by tracing real failed tool calls, not
from general PowerShell knowledge.

| Symptom | Cause | Fix |
|---|---|---|
| A cmdlet-only call (`Get-ChildItem`, `Get-Process`, a pipeline of both) prints correct output, no error text, but the wrapper reports it **failed** | `$LASTEXITCODE` is set only by native executables, never reset by a cmdlet. An earlier native failure in the same session (a failed `wsl.exe`, `adb`, Gradle call — even one already known and not being fixed) leaves its stale value sitting there, misread as this call's result. | Don't "fix" a command whose own output is correct. Check whether an earlier native command actually failed before trusting the flag. Prefer `$?` or a caught exception over `$LASTEXITCODE` for cmdlet-only calls. |
| One PowerShell call that writes a heredoc (e.g. a Python script via `@'...'@`) and later runs `Remove-Item` in the *same* call gets blocked, citing a nonsense path like `'\n'.join` as the thing it refuses to delete | The built-in `Remove-Item` destructive-path guard scans the whole command text for quoted fragments and can grab a piece of the heredoc *body* instead of the real target, when both appear together. | Never put a heredoc and a `Remove-Item` call in the same invocation. Split: write in one call, run in a second, clean up in a third. Sequential dependency is the *reason* to split, not a reason to combine. |
| `git commit -m "$(cat <<'EOF' ... EOF)"` errors, or only its first line becomes the commit message | `<<` is bash heredoc syntax, not a PowerShell operator — it doesn't parse. Even PowerShell's own here-string handed to a native exe's single `-m` arg only survives as line one. | Use the Bash tool for a multi-line `git commit` message. If it must be PowerShell, write the message to a temp file with a here-string and pass `-F <file>`. |
| A file PowerShell wrote (`Out-File`, `Set-Content`, `>`) comes out garbled elsewhere — `json.loads` chokes, or text shows `â€"` / `ðŸ"` in place of an em-dash or emoji | These cmdlets default to UTF-16 (with BOM) or the system codepage, not UTF-8. | Pass `-Encoding utf8` explicitly whenever another tool will read the result. Recover an already-mangled file with `encoding="utf-8-sig"` on the read side, but fix the write going forward. |

## Why these four

Rows 1-2 are false signals — the wrapper's success/failure read is wrong. Rows 3-4 are
bash habits not transferring: syntax that looks equivalent but isn't. Each has already
cost a wasted debugging pass, a scrapped fix, or a mangled file.

