AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

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 the win_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 the win_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 the copy 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 walkthroughmanaging inventory in AnsibleAnsible Windows playbook patterns

See also

Ansible Run Python Scripts: Execute & Manage Python on Remote Hosts

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home