misaka-mikoto-tech/agent-skills · Archived

powershell-safe-invocation

Use when writing or running PowerShell on Windows, especially native programs, quoted paths, escaping, pwsh, Start-Process, file operations, or shell troubleshooting.

First seen Jun 30, 2026

Installation

$ npx skills add misaka-mikoto-tech/agent-skills --skill powershell-safe-invocation

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from misaka-mikoto-tech/agent-skills.

npx skills add misaka-mikoto-tech/agent-skills

Browse all from misaka-mikoto-tech/agent-skills

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 252
License LICENSE
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 7,343 B
  • docs SUMMARY.md 200 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 39 installs

SKILL.md

PowerShell Safe Invocation

Shell

Use PowerShell 7 through pwsh.exe unless Windows PowerShell 5.1 is explicitly required.

When the active shell is uncertain, verify:

$PSVersionTable.PSVersion
$PSNativeCommandArgumentPassing

Do not assume installing PowerShell 7 makes powershell.exe use PowerShell 7:

  • pwsh.exe = PowerShell 7
  • powershell.exe = Windows PowerShell 5.1

Native Programs

Never construct one large command string when arguments can be passed separately.

Use:

$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:

  • Treat every native argument as one array item.
  • Invoke executable paths stored in variables with &.
  • Capture $LASTEXITCODE immediately.
  • Avoid using $args as your own argument array name; it is a PowerShell automatic variable. Use names like $argList or $nativeArgs.
  • Do not use Invoke-Expression.
  • Do not add a cmd.exe /c layer merely to launch an executable.
  • Do not use Bash-style \" escaping in PowerShell.

Cmdlets

Use hashtable splatting for PowerShell cmdlets:

$params = @{
    LiteralPath = 'C:\Data[1]\input.txt'
    Destination = 'C:\Output'
    Force       = $true
    ErrorAction = 'Stop'
}

Copy-Item @params

Use -LiteralPath for concrete paths when the cmdlet supports it. For cmdlets that expose only -Path, such as New-Item, use -Path; when unsure, check Get-Command <cmdlet> -Syntax.

Do not use $LASTEXITCODE to test a PowerShell cmdlet. Use terminating errors:

$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.

Complex Commands

Avoid deeply quoted commands such as:

cmd.exe /c pwsh.exe -Command "..."

For multiline code, nested quotes, JSON, XML, regular expressions, pipelines, redirection, or non-ASCII paths:

  1. Write a temporary .ps1 file.
  2. Execute it with:
pwsh.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:

pwsh.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.

Strings And Multiline Code

  • Use single quotes for literal strings and paths.
  • Use double quotes only when PowerShell expansion is needed.
  • Avoid backtick line continuation; use arrays, hashtables, splatting, parentheses, or script blocks.
  • Do not use Bash heredocs such as python - <<'PY'; PowerShell parses < differently. Use a temporary script file or a PowerShell here-string piped to the program.
  • For JSON, create objects and use ConvertTo-Json; do not hand-escape JSON.
  • Use single-quoted here-strings for literal multiline text: put no characters after opening @', and close with '@ alone at the start of a line.

Encoding

PowerShell 7 defaults to UTF-8 without BOM for text output; Windows PowerShell 5.1 defaults vary by cmdlet.

  • For a new text file consumed by another tool, specify its required encoding explicitly (usually utf8).
  • Before changing an existing text file, identify and preserve its existing encoding. Do not silently convert GBK, UTF-16, or BOM-sensitive files; if the encoding is unclear, inspect or ask.
  • Do not set 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.
  • Do not apply text encoding options to binary files. Use byte APIs for binary data.

Start-Process

For normal foreground execution, use:

& $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:

$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)"
}

File Operations

Before recursive delete, move, or overwrite:

  • Resolve the absolute root and target paths.
  • Verify the target is inside the intended root.
  • Reject empty, root-level, or unexpected paths.
  • Keep filesystem mutations in PowerShell instead of passing paths to another shell.

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.

Version And Module Differences

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:

$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:

Format-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.

Decision Order

Choose the simplest safe option:

  1. PowerShell cmdlet.
  2. & $exe @argList.
  3. Temporary .ps1 file with pwsh.exe -File.
  4. ProcessStartInfo.ArgumentList.
  5. Start-Process when its special behavior is required.
  6. cmd.exe /c only when cmd semantics are required.
  7. Invoke-Expression only as a tightly controlled last resort.

For uncommon cases and complete examples, read reference.md.