[FEATURE] Make `allowed-tools` wildcards in Skills work with `pwsh`

Resolved 💬 4 comments Opened Nov 10, 2025 by Dennis-Renz Closed Jan 15, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

I want to be able to write skills that

  • Are supplied together with a powershell script (e.g. my-skill/scripts/my-script.ps1) or are using a powershell commandlet
  • Dynamically pass arguments to these scripts (e.g. the name of a directory or branch to create)
  • Don't require user interaction, i.e. the script usages are approved via allowed-tools

This is currently not possible, I have tried several options and none worked. Notably, it is possible if the scripts use bash.

Proposed Solution

Ideally, this just works, as it is consistent with how allowed tools are specified for bash scripts:

allowed-tools: Bash(New-Item:*), Bash(pwsh -Command "New-Item:*)

An interesting solution was proposed by Copilot Auto-Complete: Maybe something like this would be nice UX:

allowed-tools: PowerShell(New-Item:*)

Alternative Solutions

A workaround that works is to use bash scripts instead.

Priority

Medium - Would be very helpful

Feature Category

Configuration and settings

Use Case Example

Creating a Directory

Powershell

This is a test skill that creates a directory using New-Item. There aren't any dynamic arguments involved here so it would be possible to allow this by putting the exact invocation Bash(pwsh -Command "New-Item -Path test -ItemType Directory") inside allowed-tools, but it's to illustrate the point. There's an example with dynamic arguments down below.

````markdown
---
name: pwsh-new-item
description: Test skill to debug how to allow script execution in a skill. Use only when prompted to do so.
allowed-tools: Bash(New-Item:), Bash(pwsh -Command "New-Item:)
---

Test Script Execution

Instructions

Run the following

New-Item -Path test -ItemType Directory

````

Trying to run this results in a requested confirmation:

<img width="583" height="527" alt="Image" src="https://github.com/user-attachments/assets/1124d7b4-1d50-47e3-96d7-b12d637b09da" />

Bash

We can easily do the same in bash, without having to specify the full command:

````markdown
---
name: bash-mkdir
description: Test skill to debug how to allow script execution in a skill. Use only when prompted to do so.
allowed-tools: Bash(mkdir:*)
---

Test Script Execution

Instructions

Run the following

mkdir test

````

<img width="781" height="349" alt="Image" src="https://github.com/user-attachments/assets/05db392c-32c0-41d2-96e5-c246fca812e8" />

Passing dynamic arguments

PowerShell

This is where our use case originated from, here's a demo:

````markdown
---
name: pwsh-greeting
description: Test skill to debug how to allow script execution in a skill. Use only when prompted to do so.
allowed-tools: Bash(pwsh ~/.claude/skills/pwsh-greeting/scripts/greeter.ps1:), Bash(pwsh "C:\Users\dennis.renz\.claude\skills\pwsh-greeting\scripts\greeter.ps1":)
---

Test Script Execution

Instructions

Run the following

~/.claude/skills/pwsh-greeting/scripts/greeter.ps1 -Name "Claude"

````

With the accompanying script at scripts/greeter.ps1:

param(
    [Parameter(Mandatory=$true)]
    [string]$Name
)

Write-Output "Hello, $Name! Welcome!"

<img width="857" height="515" alt="Image" src="https://github.com/user-attachments/assets/141b1564-e94a-4878-b464-dbd8227a4bfa" />

Bash

Again, this is easily doable in bash:

````markdown
---
name: bash-greeting
description: Test skill to debug how to allow script execution in a skill. Use only when prompted to do so.
allowed-tools: Bash(~/.claude/skills/bash-greeting/scripts/greeter.sh:), Bash("C:\Users\dennis.renz\.claude\skills\bash-greeting\scripts\greeter.sh":)
---

Test Script Execution

Instructions

Run the following

~/.claude/skills/bash-greeting/scripts/greeter.sh --name "Claude"

````

with the accompanying scripts/greeter.sh:

#!/bin/bash

Name=""

while [[ $# -gt 0 ]]; do
    case $1 in
        --name)
            Name="$2"
            shift 2
            ;;
        *)
            echo "Error: Unknown option $1"
            echo "Usage: $0 --name <Name>"
            exit 1
            ;;
    esac
done

if [ -z "$Name" ]; then
    echo "Error: --name parameter is required"
    echo "Usage: $0 --name <Name>"
    exit 1
fi

echo "Hello, $Name! Welcome!"

This works just fine:

<img width="1105" height="340" alt="Image" src="https://github.com/user-attachments/assets/c65bb160-2a25-4b0e-8c0c-36ab0d13c04b" />

Additional Context

_No response_

View original on GitHub ↗

This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗