●AUTO — From August 14, auto mode becomes the default in Claude Code for Pro, Max, and Team. It only stops for actions judged irreversible, destructive, or aimed outside your environment●SAFETY — In a study with 1,053 paid testers, auto mode caught 89% of harmful actions while human review caught 13.6%●HABIT — Manual review becomes habitual, Anthropic notes: users approve 97% of the permission prompts Claude Code shows them●GUARD — Prompt injection screening and customizable hard deny rules have been added to keep things like data exfiltration off the table●VOICE — The head of Claude Code says he and his team have used auto mode exclusively for months and cannot imagine going back to permission prompts●VERSION — The latest release is v2.1.226 from August 8, bug fixes and reliability only. Workbench retires August 17, and Sonnet 5 promo pricing runs through August 31●AUTO — From August 14, auto mode becomes the default in Claude Code for Pro, Max, and Team. It only stops for actions judged irreversible, destructive, or aimed outside your environment●SAFETY — In a study with 1,053 paid testers, auto mode caught 89% of harmful actions while human review caught 13.6%●HABIT — Manual review becomes habitual, Anthropic notes: users approve 97% of the permission prompts Claude Code shows them●GUARD — Prompt injection screening and customizable hard deny rules have been added to keep things like data exfiltration off the table●VOICE — The head of Claude Code says he and his team have used auto mode exclusively for months and cannot imagine going back to permission prompts●VERSION — The latest release is v2.1.226 from August 8, bug fixes and reliability only. Workbench retires August 17, and Sonnet 5 promo pricing runs through August 31
Claude Code's PowerShell Tool — A Native Windows Path That Bypasses WSL
Setup and practical use of the Claude Code PowerShell tool on Windows — when it actually beats WSL2, security hardening for corporate environments, and real automation patterns from daily use.
When the WSL2 Round-Trip Started Feeling Slow — v2.1.84
Claude Code v2.1.84, released in April 2026, introduced the PowerShell tool as an opt-in preview. This is a significant milestone for Windows developers: you can now use PowerShell as a native tool within Claude Code sessions, without needing to route everything through WSL (Windows Subsystem for Linux).
Until now, Windows users typically relied on WSL2 and Bash to interact with Claude Code. The PowerShell tool opens up native Windows capabilities — file system operations, registry access, Azure/Active Directory integration, and more — directly from your Claude Code workflow.
What Problem Does the PowerShell Tool Solve?
Working with Claude Code on Windows before this release came with a few pain points:
Limitations of the WSL2 approach:
Mixed path formats between Windows and Linux (\\wsl$\ paths) caused frequent resolution errors
Accessing the Windows registry or COM objects required workarounds
Integrations with Active Directory or Azure AD needed extra bridging layers
The PowerShell tool eliminates these friction points, bringing native Windows development and IT operations directly into Claude Code.
✦
Thank you for reading this far.
Continue Reading
What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.
WHAT YOU'LL LEARN
✦Enabling the PowerShell tool through persistence: the three Windows-specific pitfalls with the exact fix code for each
✦A measured startup-overhead comparison of the PowerShell tool vs. WSL2 on one repo (~190ms vs ~1,050ms cold)
✦Six practical recipes — winget bootstrap, gh PRs, dotnet coverage, Stripe/Firebase CLIs — each with an unattended-run safety gate
Secure payment via Stripe · Cancel anytime
✦
Unlock This Article
Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.
Before enabling the PowerShell tool, make sure you have the following:
Claude Code v2.1.84 or later
Windows 10 / 11 or Windows Server 2019 / 2022
PowerShell 5.1 or PowerShell 7.x (recommended)
Node.js 18 or later (Claude Code runtime)
To check your PowerShell version:
# Check PowerShell version$PSVersionTable.PSVersion# Example outputMajor Minor Build Revision----- ----- ----- --------7 4 7 0
PowerShell 7.x (PowerShell Core) is strongly recommended for its improved security features and cross-platform design.
How to Enable the PowerShell Tool
The PowerShell tool is currently an opt-in preview. Here are two ways to turn it on:
Option 1: Via the /config Menu
Launch Claude Code and run the /config command:
/config
Navigate to "Tools & Execution" in the settings menu. Find the "PowerShell Tool (Preview)" entry and press Enter to enable it. Press Esc to cancel, or Enter to save your changes.
Option 2: Edit settings.json Directly
Open ~/.claude/settings.json (on Windows: %USERPROFILE%\.claude\settings.json) and add the following:
Set "version" to "pwsh" for PowerShell 7 or "powershell" for Windows PowerShell 5.1. Restart Claude Code after saving to apply the changes.
Verifying the Setup
Once Claude Code restarts, you can confirm the tool is active by asking:
Do your available tools include PowerShell?
If everything is configured correctly, Claude will confirm it can execute PowerShell commands.
Basic Usage
With the PowerShell tool enabled, Claude Code can execute PowerShell alongside Bash. On Windows, it will automatically select the appropriate tool based on context.
File and Directory Operations
# List all TypeScript files recursivelyGet-ChildItem -Path . -Recurse -Filter "*.ts" | Select-Object FullName# Read file contentsGet-Content .\src\components\Button.tsx# Create a new directoryNew-Item -ItemType Directory -Path ".\src\features\auth"# Create a backup of a config fileCopy-Item .\config.json .\config.json.bak
Gathering System Information
# Check installed Node.js versionnode --version# Output: v22.14.0# Available memoryGet-CimInstance Win32_OperatingSystem | Select-Object FreePhysicalMemory, TotalVisibleMemorySize# Read a user environment variable[System.Environment]::GetEnvironmentVariable("PATH", "User")
Package Management
# List top-level npm packagesnpm list --depth=0# Update global packagesnpm update -g# Install with pnpm (frozen lockfile)pnpm install --frozen-lockfile
Security Features Explained
The v2.1.84 release introduced several hardened security behaviors specifically for the PowerShell tool. These integrate with Claude Code's existing dangerous-command detection system.
Background Job Bypass Prevention
The PowerShell & operator at the end of a command can be used to sidestep security checks by running processes in the background. Claude Code detects trailing & usage and prompts for confirmation before proceeding.
# ⚠️ This will trigger a confirmation promptStart-Process notepad.exe &# ✅ Normal execution — no promptStart-Process notepad.exe
-ErrorAction Break Control
The -ErrorAction Break parameter can cause the PowerShell debugger to hang in certain conditions. Claude Code monitors for this and handles it safely so your session stays responsive.
Archive Extraction TOCTOU Prevention
Commands like Expand-Archive are checked for path safety before executing. This guards against Time-of-Check-Time-of-Use (TOCTOU) attacks where the target path could change between validation and execution.
PS 5.1 Argument Splitting Hardening
When external command arguments contain both double-quotes and whitespace, PowerShell 5.1 has known argument-splitting quirks. Claude Code detects this pattern and prompts for confirmation rather than auto-approving.
# ⚠️ Claude Code will prompt for this on PS 5.1# (arguments contain double-quotes AND whitespace)& "C:\Program Files\MyApp\app.exe" "input file.txt"
Persistent Setup Patterns and Windows-Specific Pitfalls
So far we've covered /config and settings.json for enabling the tool, but in practice you'll hit Windows-specific issues: settings disappearing after reboot, VS Code not picking them up, PowerShell execution policies blocking scripts. Here are three persistence patterns I've settled on after running this on multiple Windows development machines.
Pattern 1: PowerShell Profile ($PROFILE) — Personal Dev Machines
Writing the environment variable into $PROFILE (loaded on every PowerShell start) is the most flexible and recommended approach.
# Find the profile path (will be created if missing)echo $PROFILE# Example: C:\Users\YourName\Documents\PowerShell\Microsoft.PowerShell_profile.ps1# Edit itnotepad $PROFILE
Add this line and save:
# Enable Claude Code PowerShell tool by default$env:CLAUDE_CODE_USE_POWERSHELL_TOOL = "1"
The setting takes effect in new terminals. To apply immediately in the current shell, run . $PROFILE.
Pattern 2: Windows System Environment Variable — Team Distribution
If you launch from multiple terminals or GUI tools (VS Code, Cursor, etc.) and want the variable always set, register it as a Windows system environment variable.
Windows key → search "environment variables" → "Edit the system environment variables"
Combined with Pattern 1 or 2 above, the variable is inherited automatically in the integrated terminal.
Common Pitfall: "Running Scripts Is Disabled on This System"
You may hit Set-ExecutionPolicy restrictions occasionally. In some organizations the policy can't be changed, so check the current state before deciding.
# Check the current policyGet-ExecutionPolicy# Allow scripts for the current user (the most conservative useful change)Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
RemoteSigned allows local scripts and requires signature verification only for downloaded ones — a reasonable middle ground for individual developers and small teams. On managed corporate PCs, check with IT before changing this.
Real-World Workflow Examples
1. Azure Resource Management
# Show current Azure account detailsaz account show --output json | ConvertFrom-Json | Select-Object name, id# List all resource groupsaz group list --output table# Check App Service running stateaz webapp show --name my-app --resource-group my-rg --query "state" --output tsv
You can ask Claude directly:
List all resources in our dev resource group and identify any App Services
that haven't been accessed in the past 30 days.
2. Active Directory / Entra ID Operations
# Import the AD module (requires domain-joined machine)Import-Module ActiveDirectory# Check which groups a user belongs toGet-ADUser -Identity "john.doe" -Properties MemberOf | Select-Object MemberOf# Find disabled accountsSearch-ADAccount -AccountDisabled -UsersOnly | Select-Object Name, SamAccountName
3. Windows Event Log Analysis
# Get error events from the last 24 hours$since = (Get-Date).AddHours(-24)Get-WinEvent -LogName "Application" -FilterHashtable @{ Level = 2 StartTime = $since} | Select-Object TimeCreated, Id, Message | Format-Table -AutoSize
Ask Claude to "analyze the application event log for anomalies," and it will run this query and interpret the results for you.
The PowerShell tool is fully integrated with Claude Code's /env command. Environment variables you set persist across both Bash and PowerShell tool invocations within the same session.
This makes it easy to simulate CI/CD environments or manage secrets locally during development.
Troubleshooting
Error: "Running scripts is disabled on this system"
File C:\...\script.ps1 cannot be loaded because running scripts is disabled on this system.
Fix: Check and update your PowerShell execution policy.
# See current policiesGet-ExecutionPolicy -List# Allow local scripts for the current user (recommended)Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Error: "pwsh is not found"
This happens when settings.json specifies "version": "pwsh" but PowerShell 7 isn't installed.
# Install PowerShell 7 via wingetwinget install --id Microsoft.PowerShell -e# Or download the MSI directly from GitHub Releases# https://github.com/PowerShell/PowerShell/releases
Restart Claude Code after installation.
Too Many Confirmation Prompts
If harmless commands are triggering confirmation dialogs, you can add them to an allow-list:
Default to PowerShell 7. It's faster, cross-platform, has better security primitives, and supports newer syntax. The exception is when a Windows-only module like ActiveDirectory ships only for 5.1 — in that case, switch back per task. There's no global "right answer" here, but 7 is the right starting point.
Does the PowerShell tool make WSL2 obsolete?
Not quite. WSL2 still wins when you need Linux-specific tooling, Docker, or native Python/C builds. The PowerShell tool wins for Windows-native administration and .NET automation. The rule of thumb I use: "Linux-leaning task → WSL2, Windows-leaning task → PowerShell tool."
Recipe 1: Bootstrapping a Project with winget
Every README has a "install these tools" section, and most teams still install them by hand. Asking Claude to run a small winget block solves it once and gracefully skips already-installed tools.
# What runs when you ask Claude: "install everything this repo needs via winget"$tools = @("Microsoft.PowerShell", "GitHub.cli", "Microsoft.DotNet.SDK.9", "Microsoft.VisualStudioCode")foreach ($id in $tools) { if (-not (winget list --id $id -e --accept-source-agreements 2>$null | Select-String $id)) { winget install --id $id -e --silent --accept-source-agreements --accept-package-agreements } else { Write-Host "Skip: $id (already installed)" }}
The detail that matters is the winget list check before winget install. Skipping it leads Claude into double-installs that error out the whole script.
Recipe 2: Pairing PR Workflows with the gh CLI
GitHub CLI is fine in WSL, but installing gh on the Windows side lets you push and open PRs directly from PowerShell Tool calls. My favorite shortcut is to ask Claude to apply edits, commit, push, and open a PR in one go.
gh pr create --fill --web autofills the body and opens the browser, so you keep a final review checkpoint without slowing down. If you'd rather have Claude write the body, swap --fill for --body "$(cat .git/CLAUDE_NOTE.md)".
Recipe 3: One Command for dotnet Test + Coverage
dotnet test alone doesn't give you coverage; you usually need coverlet. Saving the right invocation as a recipe means Claude reproduces the same quality gate every time.
PowerShell's backtick line continuation feels odd if you came from Bash. Tell Claude once to break long commands with backticks and it sticks to that style.
Recipe 4: Crossing the WSL/PowerShell Boundary Safely
Even after PowerShell Tool gets traction, you still want WSL for tools that shine on Linux (latest ripgrep, jq, and friends). Calling WSL from PowerShell is the bridge — but path translation is where it bites.
# Correct way to grep a Windows path from WSL$winPath = "C:\Users\me\proj"$wslPath = wsl wslpath -a "$winPath"wsl rg --hidden --no-ignore "TODO" $wslPath
wslpath -a converts cleanly to POSIX form. Hand C:\Users\me\proj directly to WSL and you'll get "No such file" — Claude will keep doing this unless you record the recipe.
Recipe 5: Wiring Stripe and Firebase CLIs Into the Loop
I keep Stripe CLI and Firebase CLI on the Windows side. Once Claude can reach them through PowerShell Tool, debugging payments and AdMob feels notably less painful.
# Pull the last 100 events and surface only the failed payment intentsstripe events list --limit 100 --format json | ` ConvertFrom-Json | ` Where-Object { $_.type -like "*payment_intent.payment_failed*" } | ` Select-Object id, created, type, @{n="amount";e={$_.data.object.amount}} | Format-Table -AutoSize
Ask Claude "show me recent payment failures" and it will write and run something like this. Save the pattern in your CLAUDE.md ("for Stripe event analysis, use ConvertFrom-Json filters") so the next conversation skips the explanation.
Recipe 6: Restarting Windows Services Without Permission Surprises
Restart-Service often requires admin. Without guardrails, Claude tries it, hits a permission error, and silently moves on. I have Claude write a wrapper that explicitly nudges toward elevation when needed.
Through PowerShell Tool, -Verb RunAs opens a separate elevated process so the elevation prompt never blocks your existing session.
Before You Let These Run Unattended — Gate the Risky Operations
These recipes are comfortable when you watch each result, but Auto Mode changes the calculus. Commands that rewrite your environment — winget install, Restart-Service — can suddenly run without a confirmation step.
My rule of thumb is: let reads and lookups through, but pause on anything that changes state. The sturdiest PowerShell-side move is to add -WhatIf to state-changing cmdlets so Claude shows the plan first.
# Preview destructive operations with -WhatIf before applyingfunction Invoke-ServiceRestartSafely { param([string]$ServiceName, [switch]$Apply) if (-not $Apply) { Restart-Service -Name $ServiceName -WhatIf Write-Host "Plan only. Re-run with -Apply to execute." return } Restart-Service -Name $ServiceName -Force}
Note in your CLAUDE.md that destructive operations should be previewed with -WhatIf first, so cmdlets like Restart-Service or Remove-Item don't run for real on their own. Pair that with Claude Code's /permissions — allow lookups such as winget list, but require confirmation for installers like winget install — and even an unattended session keeps a hard stop right before anything that could break. It dovetails nicely with the elevation-prompt wrapper from Recipe 6.
Sharing Recipes Across a Team
You can keep these in your personal Microsoft.PowerShell_profile.ps1, but I prefer dropping them in .tools/recipes.ps1 at the repo root so the team picks them up. Note the path in CLAUDE.md ("dot-source .tools/recipes.ps1 before running PowerShell"), and Claude will load the same recipes every session.
A Quick Benchmark: Startup Overhead vs. Going Through WSL2
Rather than settling the switch decision purely in my head, I ran the same task through both paths on a Windows 11 machine and measured the startup overhead. The task is deliberately light: listing the .ts files under the current directory.
# Measured through the PowerShell toolMeasure-Command { Get-ChildItem -Recurse -Filter *.ts | Out-Null } | Select-Object -ExpandProperty TotalMilliseconds# The same work through WSL2 (bash + find)Measure-Command { wsl find . -name '*.ts' | Out-Null } | Select-Object -ExpandProperty TotalMilliseconds
Running each five times against the same repository (~1,200 files), the median results looked like this:
Path
First call (cold)
Subsequent (warm)
PowerShell tool (native)
~190ms
~150ms
Via WSL2 (wsl find)
~1,050ms
~430ms
The absolute numbers shift with the machine and disk state, of course. But the pattern — WSL2 adding a fixed cost to the first invocation — held every time I re-measured. For a single heavy task it disappears into the noise. For a workflow that re-reads environment variables and fires dozens of small commands in a row, that fixed cost starts to shape how fast the loop feels.
Tomorrow morning, add one line to your repo's README: which PowerShell script Claude should run first via the PowerShell Tool. Even something as small as "run ./scripts/setup.ps1 before anything else" reshapes how Claude opens its first session. Recipes are an asset that compound — the work pays back the second time you reach for them.
Share
Thank You for Reading
Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.