Claude Code Use PowerShell Tool: Windows Setup Guide
If you run Claude Code on Windows, you've probably noticed it doesn't always drop into bash the way it does on macOS or Linux. On native Windows, Claude Code uses PowerShell as its shell tool for running commands, editing files through scripts, and executing build or test steps. This article explains how that works, how to configure it, and how to fix the most common issues people hit.
The short answer to "how do I get Claude Code to use PowerShell" is: on native Windows installs, it already does by default. Claude Code detects the host shell and picks PowerShell (or cmd.exe as a fallback) unless you're running inside WSL, in which case it uses bash instead. You don't need to explicitly request PowerShell — the tool-use layer negotiates the shell automatically based on your environment.
How Claude Code Picks a Shell
Claude Code's agent loop includes a shell/execute tool that the model calls when it needs to run a command — installing a package, running tests, checking git status, and so on. Under the hood, this is the same tool-use mechanism described in Claude's general tool-calling API: the model emits a structured call, the client executes it, and the result goes back into the conversation.
On Windows specifically, three things determine which shell gets used:
- Native Windows terminal (PowerShell 5.1 or PowerShell 7+): Claude Code defaults to PowerShell.
- WSL (Windows Subsystem for Linux): Claude Code detects the Linux environment and uses
bash, same as on macOS/Linux. - Git Bash or other POSIX shells on Windows: behavior can vary — some setups still route through PowerShell for compatibility, since Claude Code's execute tool needs a predictable shell to parse output correctly.
If you're seeing PowerShell syntax in commands Claude Code generates (things like Get-ChildItem instead of ls, or $env:PATH instead of $PATH), that's expected — the model is adapting its output to the detected shell.
Configuring PowerShell as the Default Shell
In most cases there's nothing to configure — it's automatic. But if you want to force a specific shell or you're troubleshooting a mismatch, check these:
- Launch Claude Code from the shell you want it to use. If you start it from a native PowerShell window, it inherits that environment. Starting it from WSL's terminal gives you
bashinstead, even on the same machine. - Check your execution policy. PowerShell blocks unsigned scripts by default. If Claude Code's commands fail silently or throw permission errors, run:
Get-ExecutionPolicy
If it returns Restricted, you'll need to relax it for your user scope:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
This allows locally created scripts to run while still requiring signatures for downloaded ones — a reasonable middle ground for development machines.
- Confirm PATH resolution. Claude Code relies on the shell's PATH to find tools like
npm,git, orpython. If a command that works fine when you type it manually fails when Claude Code runs it, open a fresh PowerShell window and run$env:PATH -split ';'to check the tool is actually on the path Claude Code inherits — not just a path set in a different profile or terminal.
Why PowerShell Instead of CMD
PowerShell is the default over legacy cmd.exe for a few practical reasons relevant to how Claude Code executes commands:
- Structured output: PowerShell cmdlets return objects, not just text, which makes parsing command results more reliable for the agent loop.
- Better error handling: PowerShell surfaces exceptions and exit codes more consistently than
cmd.exe, which matters when Claude Code needs to decide whether a tool call succeeded or failed. - Native support for modern workflows: things like
Invoke-WebRequest,Test-Path, and pipeline chaining map more cleanly to the kinds of multi-step operations coding agents perform.
If your workflow specifically needs cmd.exe semantics (batch files, legacy build scripts), you can usually still run them from within PowerShell using cmd /c <command>, and Claude Code will happily wrap commands that way when asked.
Common Errors and Fixes
"Cannot be loaded because running scripts is disabled on this system." This is the execution policy issue above — fix it with Set-ExecutionPolicy as shown.
Commands work manually but fail through Claude Code. Usually a PATH or working-directory mismatch. Make sure you launched Claude Code from the project directory, and that any tools it needs (node, git, docker) are installed for the same user account and shell profile it's inheriting from.
Unexpected quoting or escaping issues. PowerShell quoting rules differ from bash. If a command with special characters fails, try wrapping arguments differently — PowerShell treats backticks as escape characters, not backslashes, which trips up commands copied from Unix-oriented docs.
Long-running commands time out or hang. Claude Code's shell tool expects commands to complete or produce output within a reasonable window. Interactive commands that wait for input (like some install wizards) will stall — add non-interactive flags (-y, --silent, -Force) where the tool supports them.
Building Your Own Shell-Aware Agent
If you're building a custom coding agent or internal tool that also needs to call shell commands based on Claude's tool-use output — separate from Claude Code itself — you'll need reliable API access with streaming and structured tool calls. SubToAPI turns your existing Claude access into an HTTPS API with application keys, streaming responses, and full tool-use support, so you can wire up your own execute-tool logic (PowerShell, bash, or otherwise) without managing separate provider credentials. The tool use docs cover how tool calls and results are structured if you're implementing this yourself.
questions
Does Claude Code always use PowerShell on Windows? Yes, by default, when launched from a native Windows terminal. If you launch it from WSL, it uses bash instead, matching that environment.
Can I force Claude Code to use bash on Windows instead of PowerShell? Run Claude Code from within WSL or Git Bash rather than a native PowerShell/cmd window — it inherits the shell of the terminal it's started from.
Why do commands fail in Claude Code but work when I type them myself? It's almost always an execution policy, PATH, or working-directory mismatch between the shell you're testing in and the one Claude Code inherited at launch.