Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when writing or running PowerShell on Windows, especially native programs, quoted paths, escaping, pwsh, Start-Process, file operations, or shell troubleshooting.
.claude/skills/misaka-mikoto-tech-powershell-safe-invocation/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 39% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 26% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 46% | 0% |
| case-04 | ✗→✓ | ▲ Improved | -14% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 51% | 0% |
Use PowerShell 7 through pwsh.exe unless Windows PowerShell 5.1 is explicitly required.
When the active shell is uncertain, verify:
powershell$PSVersionTable.PSVersion $PSNativeCommandArgumentPassing
Do not assume installing PowerShell 7 makes powershell.exe use PowerShell 7:
pwsh.exe = PowerShell 7powershell.exe = Windows PowerShell 5.1Never construct one large command string when arguments can be passed separately.
Use:
powershell$exe = 'C:\Path With Spaces\tool.exe' $argList = @( '--input' 'C:\Data Folder\input.json' '--flag' ) & $exe @argList $exitCode = $LASTEXITCODE if ($exitCode -ne 0) { throw "$exe failed with exit code $exitCode" }
Rules:
&.$LASTEXITCODE immediately.$args as your own argument array name; it is a PowerShell automatic variable. Use names like $argList or $nativeArgs.Invoke-Expression.cmd.exe /c layer merely to launch an executable.\" escaping in PowerShell.Use hashtable splatting for PowerShell cmdlets:
powershell$params = @{ LiteralPath = 'C:\Data[1]\input.txt' Destination = 'C:\Output' Force = $true ErrorAction = 'Stop' } Copy-Item @params
Use -LiteralPath for real paths unless wildcard expansion is intentional.
Do not use $LASTEXITCODE to test a PowerShell cmdlet. Use terminating errors:
powershell$ErrorActionPreference = 'Stop'
Wrap expressions passed as parameter values in parentheses or assign them first: use Select-Object -Index (100..120), not -Index 100..120.
Do not pipe directly from statement syntax such as foreach (...) { ... } | ...; assign the statement output first or use the pipeline cmdlet ForEach-Object.
Avoid deeply quoted commands such as:
textcmd.exe /c pwsh.exe -Command "..."
For multiline code, nested quotes, JSON, XML, regular expressions, pipelines, redirection, or non-ASCII paths:
.ps1 file.textpwsh.exe -NoLogo -NoProfile -NonInteractive -File script.ps1
Prefer -File over -Command for anything beyond a short, simple expression.
Do not add -ExecutionPolicy Bypass unless execution policy is actually blocking a trusted script.
When you must pass a script through -Command from an outer PowerShell process, remember that the outer shell expands $variables first. Use an outer single-quoted script string when the inner script contains $p, $env:..., $PSVersionTable, or similar:
powershellpwsh.exe -NoLogo -NoProfile -Command '$p = "C:\Data Folder\input.txt"; Test-Path -LiteralPath $p'
If the command has to cross multiple interpreters or wrappers, stop and write a .ps1 file instead of stacking more quoting.
python - <<'PY'; PowerShell parses < differently. Use a temporary script file or a PowerShell here-string piped to the program.ConvertTo-Json; do not hand-escape JSON.@', and close with '@ alone at the start of a line.PowerShell 7 defaults to UTF-8 without BOM for text output; Windows PowerShell 5.1 defaults vary by cmdlet.
utf8).Console.InputEncoding or Console.OutputEncoding by default. Set them only for a confirmed terminal or native-program encoding mismatch; $OutputEncoding instead controls PowerShell text sent to native programs.For normal foreground execution, use:
powershell& $exe @argList
Use Start-Process only for elevation, new/hidden windows, detached launch, or shell behavior.
Start-Process -ArgumentList joins values into a command-line string and is not a reliable structured-argument API. Prefer ProcessStartInfo.ArgumentList when exact argument boundaries matter.
When a separate process is required and arguments are complex, use:
powershell$psi = [System.Diagnostics.ProcessStartInfo]::new() $psi.FileName = $exe $psi.UseShellExecute = $false foreach ($arg in $argList) { $psi.ArgumentList.Add($arg) } $process = [System.Diagnostics.Process]::Start($psi) $process.WaitForExit() if ($process.ExitCode -ne 0) { throw "Process failed with exit code $($process.ExitCode)" }
Before recursive delete, move, or overwrite:
Mapped drives are per user/session. If Test-Path X:\... fails under an automation or sandbox account but works interactively, check the current identity with whoami and inspect Get-PSDrive. If the mapping is not visible, ask the user for the UNC path, establish the mapping for the same account, or switch the task to a current-user/full-access execution mode when the platform supports it.
PowerShell 5.1 and PowerShell 7 can expose the same command with different parameters or command types. Verify syntax in the active shell before relying on version-specific parameters:
powershell$PSVersionTable.PSVersion Get-Command Format-Hex -Syntax Get-Command Get-FileHash -Syntax
For example, Format-Hex -Count is available in PowerShell 7 but not in Windows PowerShell 5.1. In 5.1, use pipeline limiting instead:
powershellFormat-Hex -LiteralPath 'C:\Data\buffer.bin' | Select-Object -First 2
If command discovery behaves strangely, inspect $env:PSModulePath and Get-Module -ListAvailable <ModuleName> before assuming the cmdlet is missing.
Choose the simplest safe option:
& $exe @argList..ps1 file with pwsh.exe -File.ProcessStartInfo.ArgumentList.Start-Process when its special behavior is required.cmd.exe /c only when cmd semantics are required.Invoke-Expression only as a tightly controlled last resort.For uncommon cases and complete examples, read reference.md.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 11,863 | 7,142 | -40% | 1 | 1 | 0% | 2,361 | 3,283 | +39% | 0 | 0 | — |
case-02 | fail→pass | 19,874 | 15,625 | -21% | 1 | 1 | 0% | 3,915 | 4,946 | +26% | 0 | 0 | — |
case-03 | fail→pass | 20,102 | 19,123 | -5% | 1 | 1 | 0% | 3,857 | 5,613 | +46% | 0 | 0 | — |
case-04 | fail→pass | 15,985 | 3,333 | -79% | 1 | 1 | 0% | 2,706 | 2,326 | -14% | 0 | 0 | — |
case-05 | fail→pass | 11,580 | 8,189 | -29% | 1 | 1 | 0% | 2,225 | 3,351 | +51% | 0 | 0 | — |
case-10 | fail→fail | 15,220 | 14,623 | -4% | 1 | 1 | 0% | 2,794 | 4,529 | +62% | 0 | 0 | — |
case-06 | pass→pass | 15,221 | 5,888 | -61% | 1 | 1 | 0% | 2,702 | 2,888 | +7% | 0 | 0 | — |
case-07 | fail→pass | 10,807 | 6,556 | -39% | 1 | 1 | 0% | 1,815 | 3,048 | +68% | 0 | 0 | — |
case-08 | pass→pass | 9,485 | 10,119 | +7% | 1 | 1 | 0% | 1,867 | 3,873 | +107% | 0 | 0 | — |
case-09 | pass→pass | 8,642 | 7,478 | -13% | 1 | 1 | 0% | 1,551 | 3,067 | +98% | 0 | 0 | — |
case-11 | pass→pass | 7,036 | 4,329 | -38% | 1 | 1 | 0% | 1,158 | 2,522 | +118% | 0 | 0 | — |
case-12 | pass→pass | 9,044 | 6,790 | -25% | 1 | 1 | 0% | 1,683 | 3,065 | +82% | 0 | 0 | — |
case-13 | fail→pass | 23,239 | 17,372 | -25% | 1 | 1 | 0% | 3,916 | 4,797 | +22% | 0 | 0 | — |
case-14 | fail→pass | 7,576 | 4,232 | -44% | 1 | 1 | 0% | 1,348 | 2,484 | +84% | 0 | 0 | — |
case-15 | fail→pass | 4,053 | 4,655 | +15% | 1 | 1 | 0% | 629 | 2,579 | +310% | 0 | 0 | — |
case-16 | pass→pass | 7,174 | 6,352 | -11% | 1 | 1 | 0% | 1,113 | 2,808 | +152% | 0 | 0 | — |
case-17 | fail→fail | 17,369 | 11,300 | -35% | 1 | 1 | 0% | 2,738 | 3,808 | +39% | 0 | 0 | — |
case-18 | fail→pass | 12,790 | 7,719 | -40% | 1 | 1 | 0% | 2,220 | 3,091 | +39% | 0 | 0 | — |
case-19 | pass→pass | 5,677 | 2,747 | -52% | 1 | 1 | 0% | 930 | 2,222 | +139% | 0 | 0 | — |
case-20 | pass→pass | 9,087 | 7,137 | -21% | 1 | 1 | 0% | 1,652 | 2,934 | +78% | 0 | 0 | — |
case-21 | pass→pass | 5,729 | 7,124 | +24% | 1 | 1 | 0% | 1,066 | 3,004 | +182% | 0 | 0 | — |
case-22 | pass→pass | 6,847 | 4,238 | -38% | 1 | 1 | 0% | 1,310 | 2,554 | +95% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +45 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.