本文へ移動
cccskills
無料GitHub で公開

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.

インストール方法を見る

含まれるファイル(2)

  • SKILL.md7.2 KB
  • reference.md16.0 KB

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.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Get content from Bilibili videos: official subtitles, danmaku (density/peaks/sample), comments. When no subtitles exist (no 投稿字幕), fall back to downloading audio + ASR transcription via FunASR.

日本語の概要は準備中です。原文の説明を表示しています。

Misaka-Mikoto-Tech/agent-skills2782026年9月21日 更新

Use when an agent needs to inspect or control a real Unity Editor through Locus, especially when Unity MCP is unavailable, named-pipe discovery is needed, C# must be executed, or Unity scripts must be recompiled.

日本語の概要は準備中です。原文の説明を表示しています。

Misaka-Mikoto-Tech/agent-skills2782026年9月21日 更新

Misaka-Mikoto-Tech のスキルをすべて見る

このスキルの問題を報告する