Ansible win_shell and win_command: Run Commands on Windows Complete Guide
By Luca Berton · Published 2024-01-01 · Category: installation
Complete guide to Ansible win_shell and win_command modules. Run PowerShell scripts, CMD commands, and batch files on Windows. Learn the differences between modules, handle output encoding, use creates/removes for idempotency, and troubleshoot common Windows automation issues.
win_shell and win_command run commands on Windows hosts. win_command executes a process directly (no shell). win_shell runs through PowerShell (supports pipes, redirects, variables). Here's when to use each, with practical examples.
win_command vs win_shell
| Feature | win_command | win_shell | |---------|------------|-----------| | Shell | None (direct process) | PowerShell | | Pipes | ❌ | ✅ | | Redirects | ❌ | ✅ | | Variables | ❌ | ✅ $env:PATH | | Wildcards | ❌ | ✅ | | Security | Safer (no injection) | Flexible but riskier | | Use when | Simple commands | PowerShell features needed |
win_command Examples
Basic Commands
Idempotent with creates/removes
Working Directory
win_shell Examples
PowerShell One-Liners
PowerShell Scripts
Using PowerShell Variables
Error Handling
Running Scripts from Files
win_shell with Script Files
win_script (Alternative)
Output Encoding
Real-World Examples
IIS Website Configuration
Windows Service Management
Registry Management
Prefer Dedicated Modules When Available
Use win_shell/win_command only when no dedicated module exists for the task.
FAQ
When should I use win_shell vs win_command?
Use win_command for simple executables that don't need shell features (pipes, variables, redirects). Use win_shell when you need PowerShell functionality. win_command is safer against injection since it doesn't interpret shell metacharacters.
How do I handle special characters in win_shell?
Ansible uses Jinja2 templating, which conflicts with PowerShell's $ and {{ }}. Use {% raw %}...{% endraw %} for literal PowerShell variables, or pass values through Ansible variables:
Why does my win_shell task always show "changed"?
win_shell and win_command always report changed because Ansible can't know if the command modified anything. Use changed_when to control this:
How do I run CMD (not PowerShell) commands?
Can I run elevated (admin) PowerShell?
Ansible runs as the connected user. Use become: true with become_method: runas for privilege escalation:
Conclusion
Use win_command for simple process execution and win_shell when you need PowerShell features. Always prefer dedicated Ansible modules over shell commands when available — they're idempotent and return structured data. For complex PowerShell logic, use win_shell with proper error handling, changed_when, and creates/removes for idempotency.
Related Articles • Ansible for Windows Automation • Ansible Connection Types • Ansible shell vs command vs raw • Ansible Error Handling Guide
Category: installation