- ManageEngine OpManager: Comprehensive monitoring for on-prem, cloud, and containers - Thu, Mar 23 2023
- Install K3s, a lightweight, production-grade Kubernetes distro - Mon, Mar 20 2023
- VMware NSX Advanced Load Balancer: Installation and configuration - Fri, Mar 10 2023
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.
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
Ansible notifies us at the end of running a playbook how many changes it implemented (designated in yellow).
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.
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.
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.
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.
Michael,
See my article posted here: https://www.virtualizationhowto.com/2018/04/configure-ansible-windows-server-kerberos-authentication-in-ubuntu/ as it explains how to setup kerberos authentication with Windows Servers from Ansible.
Brandon
Thanks Brandon, that looks like what I need. Cheers
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 ?
Thanks man!!! Helped out immensely.
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?
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.
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.
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
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.
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
hi
how can we create an inventory file with list of ips of the target machines using powershellin Ansible machine?is there a way.
Does this all work, when execution policy is set to AllSigned per GP?