Microsoft Windows PowerShell is a powerful, robust tool to manage Windows Servers. Using Windows PowerShell with Ansible provides many advantages over simply using PowerShell alone.

Microsoft PowerShell is arguably the most powerful scripting language for automating configuration, management, and other Microsoft workstation and server functions. It programmatically lets system administrators do just about any function they would normally perform from the GUI. This gives administrators a powerful tool to use in mass configuring both Windows workstations and server deployments.

However, some challenges hinder implementing remote PowerShell administration from scratch and interacting with Windows workstations and servers. These could include learning the ability to iterate through a group of workstation or server resources to make changes or configuration updates manually, logging the operations, and other operations. By using Windows PowerShell with Ansible, we benefit from Ansible for automation and the power of PowerShell control for Windows resources.

Advantages of using PowerShell with Ansible

Several advantages come to mind when using PowerShell with Ansible. Ansible is a configuration management and orchestration platform that allows organizing resources intelligently, defining roles, as well as writing "playbooks" that build what the server role should look like. Additionally, for those unaware, the win_modules for Ansible typically aim to interact with PowerShell through the Ansible Python interface in the backend when communicating with the Windows Server.

The underlying Ansible architecture relies heavily on PowerShell to interact with Windows Servers. Aside from this, Ansible gives Windows Server administrators the ability to interact directly with PowerShell through the normal Ansible means of controlling and managing Windows Servers via the Windows modules and playbooks. Let's see how we can do that.

For enterprise users who want to step up to the Ansible Tower solution, you get a graphical interface for controlling Windows Server configuration management and the benefits of scheduling playbooks and notifications. It also provides really nice Git integration to synchronize changes to all aspects of the environment. Ansible Tower is a paid product, however, in its unlimited form. You can run Ansible Tower free for up to 10 managed nodes, which is great for a home lab or test environment.

Ansible Tower allows GUI administration notifications and scheduling features

Ansible Tower allows GUI administration notifications and scheduling features

Using Windows PowerShell with Ansible

Special Ansible Windows modules allow running PowerShell commands on target Windows Servers. The modules you will primarily use when working with PowerShell using Ansible are the win_commandmodule and the win_shellmodule.

  • The win_commandmodule can run Windows commands including PowerShell scripts by calling the PowerShell executable. You can then feed it .PS1 scripts for consumption on the remote host. It is generally the preferred method of running scripts such as PowerShell.
  • The win_shellmodule is a less secure means of running PowerShell scripts since the user's environment affects it. It is similar to the win_command module; however, it runs the command via a shell (that defaults to PowerShell) on the target Windows Server.

Ansible win_commandexamples include:

- name: Run remote PowerShell Script
  win_command: powershell.exe -ExecutionPolicy ByPass -File C:/temp/powershellscript.ps1

Ansible win_shellexamples include:

- name: Run remote PowerShell script
  win_shell: C:\somescript.ps1 >> c:\somelog.txt

Ansible basics for controlling Windows Servers

Getting up and running with Ansible is as simple as:

  • Installing an Ansible control Linux server along with the Windows WinRM prerequisites
  • Enabling WinRM connectivity on the target Windows Servers (possible via PsExec using the ps1script
  • Setting up an inventory file to define the Windows Servers you want to control
  • Creating a playbook
  • Running the ansible-playbookcommand telling Ansible which server(s) in inventory you want to control and which playbook to run against those servers

Sample Inventory.yml file:

---

[app]
app.domain.com

[web]
web.domain.com

[db]
db.domain.com

Sample playbook:

---
- hosts: web
  tasks:
  - name: Ensure IIS webserver is installed
    win_feature:
    name: Web-Server
    state: present

Sample playbook Ansible run:

Using the templates shown above, you can easily run a playbook against your web servers using the following Ansible command:

ansible-playbook -i inventory.yml -s web.yml

Running PowerShell scripts with Ansible win_command

Using the syntax above for our Windows Server playbook to run PowerShell scripts via the win_commandmodule, we can easily run scripts on remote Windows Servers. Below, as an example, we are running a PowerShell script to set network level authentication on RDP. As you can see, the changedvalue is true, indicating implementation of the changes from the PowerShell script. I ran the Ansible script below with debugging turned on so we can see the actual script as it runs:

powershell.exe -ExecutionPolicy ByPass -File c:/Windows/Options/Get-Set-NetworkLevelAuthentication.ps1
Running a PowerShell script with the Ansible win command module

Running a PowerShell script with the Ansible win command module

Ansible notifies us at the end of running a playbook how many changes it implemented (designated in yellow).

Finished Ansible playbook noting the changes to the server

Finished Ansible playbook noting the changes to the server

Running PowerShell scripts with Ansible win_shell

With win_shellyou can run PowerShell scripts with the .PS1 extension, or you can literally run PowerShell cmdlets from the Ansible playbook itself. Again, it's worth mentioning win_shell is a less secure means of running PowerShell code on the target Windows Server hosts. Below is an example of running a quick test PowerShell script that checks for the existence of a directory and then creates a text file if it finds the directory.

- name: PowerShell Directory Test and File Create
  win_shell: |
    $value = Test-Path -Path C:\windows\temp
    if ($value) {
        New-Item C:\windows\temp\test.txt -ItemType File
    }

Shown below is the output of the Ansible playbook.

Ansible playbook output

Ansible playbook output

Copying PowerShell scripts to target Windows Servers

You may ask the question: how do you get PowerShell scripts to a target Windows Server if you want to run the script via either the win_command or win_shell module? We can use another Ansible module called win_copy that allows copying files either from the local Ansible server or from a remote share.

You could use the following code in an Ansible playbook to copy a PowerShell script housed in a localAnsible server folder (root/test/resources as in the example). The remote_srcdirective tells Ansible whether the file source is local or remote.

- win_copy:
   src: /root/test/resources/powershellscript.ps1
   dest: 'C:\temp\'
   remote_src: no

In the next stanza of the YML file for the playbook, you can then use the location of the PowerShell script above to execute it via the win_commandmodule.

- name: Run remote PowerShell Script
  win_command: powershell.exe -ExecutionPolicy ByPass -File C:/temp/powershellscript.ps1

Takeaways

Using Windows PowerShell with Ansible is a great way to interact with Windows Servers remotely using PowerShell configuration. Ansible is an easy configuration management platform to provision. It can let you get up to speed quickly with provisioning changes in a Windows Server environment. The Ansible framework gives you all the advantages that come with the product. It provides Git integration as well as the ability to use Ansible Tower, which allows additional functionality such as scheduling and notifications.

Subscribe to 4sysops newsletter!

Using the win_command, win_shell, and win_copymodules, Ansible lets you interact with PowerShell very easily and predictably on remote Windows Servers. You can use PowerShell on its own for remote configuration. However, Ansible allows orchestrating the process of PowerShell configuration, especially when building upon the Ansible concepts of roles and tasks while building playbooks.

avataravatar
14 Comments
  1. Wei-Yen Tan 5 years ago

    You can also write your own modules if they are configuration details. Doing it this way means you can write things in a ansible way.

  2. Michael Woodward 4 years ago

    Brandon, you don’t mention anything about authentication, also, how do you get this to work in a domain environment ?

    I don’t think it is quite as simple as the article makes out.

  3. sai 4 years ago

    why do we need to run powershell scripts using Ansible, is it possible to write powershell commands in the ansible module and execute on the target hosts ?

    can someone explain how user switching works in windowsenvironment, in Unix I can login using my account and switch to root for tasks that needs privileged access, how will it work in windows, can I use kerberos without storing my account passwd in the config files on ansible node and login to target host and switch to admin account for admin level tasks ?

  4. Trenton Cain 4 years ago

    Thanks man!!! Helped out immensely.

  5. prasanth 4 years ago

    Thanks a lot for article. may i know how we can pass the user interaction input to script through ansible ? so my script inside windows needs user input and we need to pass through ansible , is that possible?

  6. yaro 4 years ago

    Would be nice to see how you extract and parse the results so you can further extend your playbooks with like some variables from facts or script output.

  7. Sanjay 4 years ago

    Why do we need to run powershell scripts using Ansible, is it possible to write powershell commands in the ansible module and execute on the target hosts ?

    Also how to pass variables from Ansible yaml to PS script to execute powershell script.

    • ChrisH 3 years ago

      Running powershell scripts or running shell script blocks in your playbooks are 2 options, you don't have to choose 1 or the other. If your running a simple small block of code then running commands directly in the playbook may make sense, but for longer involved powershell scripts it may make the most sense to create a powershell script that accepts parameters.

      win_command: powershell.exe -ExecutionPolicy ByPass -File C:/temp/install.ps1 -SQLVERSION "SQL2016" -SQLEDITION "DEVELOPER" -DEBUG

  8. RonG 4 years ago

    Hey, I find your article very interesting so I tried some win_shell things myself.

    However, I came across some connectivity issues to my windows host.

    If I understand correctly, there are some prerequisites actions that need to be done before I can 

    run some playbooks over windows hosts: 

    https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html#timeout-errors

    My question: is there any easier way to run playbooks over my hosts (i.e without installations)?

     

    Thanks, Ron.

  9. Kris 3 years ago

    Hello, Thank you for such a great article, but I have a question I was hoping someone can answer..

    What permission are needed by a user account (service account) to run a powershell script remotely as a non-administrator via ansible?

    I'm successful at running powershell scripts remotely if I use and administrator account. I've not been able to execute a script using a user who is not part of the administrators group. Connecting / win_ping and reading facts works fine, i can even copy files. I've tried adding the user account i'm tyring to run the script with to the "Remote Managment Users" (this allows connectivity and limited permissions) and  added to the WinRMRmoteWMIUsers_ group as well but it didn't make any difference, I still get "access denied". I've also edited the WinRM Namespace SDDL permissions and gave both the groups and even the user account full control but no luck. 

     

    Thank you!

    Kris

  10. Vishnu Priyanka Palla 2 years ago

    hi
    how can we create an inventory file with list of ips of the target machines using powershellin Ansible machine?is there a way.

  11. Johannn Kismann 3 months ago

    Does this all work, when execution policy is set to AllSigned per GP?

Leave a reply

Please enclose code in pre tags

Your email address will not be published.

*

© 4sysops 2006 - 2023

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending

Log in with your credentials

or    

Forgot your details?

Create Account