Ansible script Module: Run Local Scripts on Remote Hosts (ansible.builtin.script)
By Luca Berton · Published 2024-01-01 · Category: installation
Complete guide to Ansible script module (ansible.builtin.script). Transfer and execute local scripts on remote hosts. Run Bash, Python, and PowerShell scripts.
Ansible is a versatile automation tool capable of managing Windows systems, including the execution of PowerShell scripts. This article explains how Ansible can run PowerShell scripts, its requirements, and best practices for integrating PowerShell into your automation workflows.
Can Ansible Run PowerShell Scripts?
Yes, Ansible can run PowerShell scripts on Windows systems. Using the win_shell and win_command modules, you can execute inline PowerShell commands or external PowerShell script files on target Windows hosts.
See also: Can Ansible Automate Windows? Complete WinRM + SSH Setup Guide (2026)
Prerequisites for Running PowerShell Scripts with Ansible
1. Enable Windows Remote Management (WinRM)
WinRM allows Ansible to communicate with Windows hosts. To enable it: Open PowerShell as Administrator. Run the following commands: winrm quickconfig
winrm set winrm/config/service/auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
Set-Item wsman:\localhost\Client\TrustedHosts -Value "<Ansible_Control_Node_IP>"
2. Install pywinrm
Install the pywinrm Python library on the Ansible control node:pip install pywinrm
3. Configure Ansible Inventory
Define your Windows hosts in the inventory file:[windows]
windows_host ansible_host=192.168.1.10 ansible_user=Administrator ansible_password=your_password ansible_connection=winrm
Using Ansible to Run PowerShell Scripts
1. Run Inline PowerShell Commands
Use thewin_shell module to execute PowerShell commands directly:
- name: Run an inline PowerShell command
hosts: windows
tasks:
- name: Get Windows services
win_shell: Get-Service | Select-Object -First 5
2. Execute PowerShell Scripts from a File
To run an external PowerShell script, use thewin_shell module:
- name: Run a PowerShell script
hosts: windows
tasks:
- name: Execute a PowerShell script
win_shell: |
powershell.exe -ExecutionPolicy Bypass -File C:\Scripts\example.ps1
3. Transfer and Execute PowerShell Scripts
If the script is not present on the Windows host, use thecopy module to transfer it first:
- name: Transfer and run a PowerShell script
hosts: windows
tasks:
- name: Copy the script to the host
copy:
src: ./example.ps1
dest: C:\Temp\example.ps1
- name: Execute the PowerShell script
win_shell: |
powershell.exe -ExecutionPolicy Bypass -File C:\Temp\example.ps1
4. Capture Command Output
You can store the output of a PowerShell script execution for further use:- name: Capture PowerShell script output
hosts: windows
tasks:
- name: Run a script and save output
win_shell: |
powershell.exe -ExecutionPolicy Bypass -Command "Get-Process"
register: process_output
- name: Display output
debug:
var: process_output.stdout
See also: Can Ansible Be Used to Manage Windows Systems?
Best Practices for Running PowerShell Scripts with Ansible
Use-ExecutionPolicy Bypass:
Ensure the PowerShell script runs without policy restrictions.
Secure Credentials:
Use Ansible Vault to encrypt sensitive information like passwords.
Test Scripts Locally:
Validate PowerShell scripts independently before running them via Ansible.
Organize Scripts:
Store scripts in a centralized scripts/ directory within your project for better management.
Enable Logging:
Add logging to your PowerShell scripts for debugging and auditing purposes.
Common Use Cases for Running PowerShell Scripts with Ansible
System Configuration: Automate tasks like enabling features, configuring firewalls, or setting registry keys. Software Deployment: Install or update applications using PowerShell automation. Service Management: Start, stop, or monitor Windows services. Data Collection: Retrieve system information or logs for reporting.See also: Can Ansible Manage Windows? Complete Windows Automation Guide
Conclusion
Ansible’s ability to execute PowerShell scripts makes it a powerful tool for managing Windows hosts. By combining Ansible’s automation capabilities with PowerShell’s scripting power, you can achieve efficient and flexible workflows tailored to your needs.
Learn More About Running PowerShell with Ansible
Run PowerShell Commands
- name: Run PowerShell command
ansible.windows.win_shell: |
Get-Service | Where-Object { $_.Status -eq 'Running' } | Select-Object Name, Status
register: services
- debug: var=services.stdout_lines
Run PowerShell Script File
From controller (script module)
- name: Run local script on remote host
ansible.builtin.script: files/setup.ps1
args:
executable: powershell.exe
From remote host (win_shell)
- name: Run remote script
ansible.windows.win_shell: C:\Scripts\deploy.ps1
args:
chdir: C:\Scripts
Pass Arguments to Scripts
- ansible.windows.win_shell: |
C:\Scripts\deploy.ps1 -Environment "{{ env }}" -Version "{{ version }}"
# Or with script module
- ansible.builtin.script: files/deploy.ps1 -Environment production -Version 2.5
args:
executable: powershell.exe
win_shell vs win_command
| Module | Shell | Pipes/Redirects | PowerShell |
|--------|-------|----------------|------------|
| win_shell | Yes | Yes | Yes |
| win_command | No | No | No |
# win_shell: full PowerShell
- win_shell: Get-Process | Sort-Object CPU -Descending | Select-Object -First 5
# win_command: simple executable
- win_command: ipconfig /all
Capture Output
- ansible.windows.win_shell: |
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"
[math]::Round($disk.FreeSpace / 1GB, 2)
register: free_space
- debug:
msg: "Free space: {{ free_space.stdout | trim }} GB"
Error Handling
- ansible.windows.win_shell: |
$ErrorActionPreference = 'Stop'
try {
Install-WindowsFeature -Name Web-Server -IncludeManagementTools
} catch {
Write-Error "Failed: $_"
exit 1
}
register: result
failed_when: result.rc != 0
Run as Different User
- ansible.windows.win_shell: |
whoami
become: true
become_user: Administrator
become_method: runas
Multi-Line Scripts
- ansible.windows.win_shell: |
# Configure IIS
Import-Module WebAdministration
$siteName = "{{ site_name }}"
$sitePath = "{{ site_path }}"
if (-not (Test-Path $sitePath)) {
New-Item -Path $sitePath -ItemType Directory
}
if (Get-Website -Name $siteName -ErrorAction SilentlyContinue) {
Remove-Website -Name $siteName
}
New-Website -Name $siteName -PhysicalPath $sitePath -Port 80
Start-Website -Name $siteName
Write-Output "Site $siteName created at $sitePath"
register: iis_result
FAQ
Can I run PowerShell 7 (pwsh)?
- ansible.windows.win_shell: |
$PSVersionTable.PSVersion
args:
executable: pwsh.exe
How do I handle PowerShell errors?
Set $ErrorActionPreference = 'Stop' and use try/catch. Check result.rc and result.stderr.
Can I run PowerShell from a Linux controller?
Yes — Ansible connects via WinRM and executes PowerShell remotely. The controller runs on Linux; PowerShell runs on the Windows target.
Run Inline PowerShell
- ansible.windows.win_shell: |
Get-Service | Where-Object {$_.Status -eq 'Running'} | Select-Object Name
register: services
- debug:
msg: "{{ services.stdout_lines }}"
Run PowerShell Script File
# Copy and run a local script on remote Windows host
- ansible.builtin.script: scripts/setup.ps1
args:
executable: powershell
# Or with the script already on the remote host
- ansible.windows.win_shell: C:\Scripts\setup.ps1
PowerShell with Parameters
- win_shell: |
C:\Scripts\deploy.ps1 -Environment Production -Version "{{ app_version }}"
register: deploy_result
no_log: "{{ 'password' in deploy_result.stdout | default('') }}"
win_command vs win_shell
# win_command — runs executables directly (no PowerShell)
- ansible.windows.win_command: ipconfig /all
register: network
# win_shell — runs through PowerShell (pipes, variables work)
- ansible.windows.win_shell: |
Get-Process | Where-Object {$_.CPU -gt 100} | Sort-Object CPU -Descending
Capture and Parse Output
- win_shell: |
Get-WmiObject Win32_LogicalDisk |
Select-Object DeviceID, @{n='FreeGB';e={[math]::Round($_.FreeSpace/1GB,2)}} |
ConvertTo-Json
register: disk_info
- set_fact:
disks: "{{ disk_info.stdout | from_json }}"
- debug:
msg: "{{ item.DeviceID }}: {{ item.FreeGB }}GB free"
loop: "{{ disks }}"
Error Handling
- win_shell: |
try {
Install-WindowsFeature -Name Web-Server -ErrorAction Stop
Write-Output "SUCCESS"
} catch {
Write-Error $_.Exception.Message
exit 1
}
register: result
failed_when: result.rc != 0
become: true
Run as Different User
- win_shell: |
whoami
become: true
become_method: runas
become_user: DOMAIN\admin
vars:
ansible_become_password: "{{ vault_admin_password }}"
Install Software with PowerShell
# Install Chocolatey packages
- win_shell: |
choco install googlechrome -y --no-progress
register: choco_result
changed_when: "'installed' in choco_result.stdout"
# Install from MSI
- win_shell: |
Start-Process msiexec.exe -ArgumentList '/i C:\Temp\app.msi /quiet /norestart' -Wait
PowerShell Remoting Requirements
# Ensure WinRM is configured (usually via inventory)
[windows:vars]
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_server_cert_validation=ignore
ansible_port=5986
FAQ
Do I need PowerShell on the Ansible controller?
No — Ansible runs PowerShell on the Windows target. The controller (Linux) communicates via WinRM.
How do I handle long-running scripts?
- win_shell: C:\Scripts\long-task.ps1
async: 3600
poll: 30
Can I use PowerShell Core (pwsh)?
- win_shell: my-script.ps1
args:
executable: pwsh # PowerShell Core instead of Windows PowerShell
Related Articles
• the Ansible Vault walkthrough • managing inventory in Ansible • Ansible Windows playbook patternsSee also
• Ansible Run Python Scripts: Execute & Manage Python on Remote HostsCategory: installation