Skip to content

windows shell safety

Kazushi Kamegawa edited this page Oct 7, 2026 · 1 revision

Windows Shell Safety Plugin

日本語

Summary

Add a standalone windows-shell-safety plugin that keeps agents from losing time on Windows when Azure CLI, JSON payloads, and pipelines pass through cmd.exe. The skill prescribes safe execution patterns, and a bundled pre-execution lint flags dangerous command shapes before they run.

Tracking

Type Issue
Parent Issue #84
Sub-issue Issue #85
Sub-issue Issue #86
Sub-issue Issue #87
Sub-issue Issue #88

Background

  • az on Windows is the batch file az.cmd. Even when called from PowerShell 7, cmd.exe re-parses its arguments and consumes |, &, <, >, ^, and %VAR%, so JMESPath such as --query "[?x=='a'] | [0]" breaks.
  • PowerShell 7.3+ defaults to $PSNativeCommandArgumentPassing = 'Windows', which keeps legacy argument passing for .cmd/.bat targets, so double quotes inside inline JSON are dropped.
  • Nested invocations such as powershell -Command "... | ..." from Git Bash or cmd let the outer shell consume pipes and quotes first.
  • Mismatched $OutputEncoding and [Console]::OutputEncoding turn non-ASCII pipeline data into ?.
  • The existing Azure DevOps guidance covers only REST writes; this plan generalizes it.

Design

  • Prevention level: skill plus pre-execution lint. No PreToolUse hook, so false positives never block work.
  • Placement: new plugin plugins/windows-shell-safety/ usable for az, gh, dotnet, and other native tools. Azure DevOps skills link to it instead of duplicating guidance.
  • Skill rules: use pwsh only; never embed JSON in arguments (UTF-8 file and @file); keep cmd metacharacters and quotes out of az --query and filter with ConvertFrom-Json; set UTF-8 encodings before pipes; run scripts with pwsh -File instead of -Command strings; lint before running; inspect received argv before retrying.
  • Test-NativeCommand.ps1: AST-based lint with rules WSS001-WSS008 (cmd /c, -Command strings, cmd metacharacters for .cmd targets, inline JSON, escaped quotes, Windows PowerShell 5.1, missing UTF-8 setup, shell workarounds). Exit code 1 on findings, -AsJson output.
  • Invoke-NativeJson.ps1: Invoke-AzJson sends bodies through a UTF-8 temporary file and returns parsed objects; -EchoArgs shows the argv a .cmd child actually received.

Implementation phases

  1. Lint script and unittest fixtures (#85).
  2. Safe execution helper (#86).
  3. Skill documentation, references, manifests, and repository docs (#87).
  4. windows-latest CI job reproducing the argument loss and proving the safe patterns (#88).

Verification

  • python3 scripts/validate_marketplaces.py succeeds.
  • The lint unittest passes locally with pwsh and in the existing Ubuntu CI job.
  • The windows-latest CI job shows the broken forms fail and the recommended forms succeed with az version, which needs no sign-in.

Clone this wiki locally