9 Ansible Playbooks for Windows Administration
I will show you a few operations that an administrator can perform on a remote windows system using ansible-playbook.
Ansible is one of the most used DevOps tools on the market today. It provides a set of Windows modules that are used to configure and manage a Windows server. I'm assuming you already have Ansible installed on Windows from where you want to manage Windows servers.
The following are some of the frequently used tasks performed by Windows administrators on a daily basis. You will be amazed to see how easy it is to administer Windows with Ansible.
The IP address of my Ansible Windows controller machine is 192.168.0.106 and the IP address of my remote Windows system is 192.168.0.102. Before you start, make sure you run the win_ping module to check if you can connect to the remote windows server or not.
[email protected] ~$ ansible win -m win_ping 192.168.0.102 | SUCCESS => { "changed": false, "ping": "pong" }
My connection to the remote host was successful.
So let's get started with Ansible Playbooks...
Copying files
win_copy is a module that copies a file from a local server to a remote Windows host. I will be using this module to copy a single PDF file.
Use the YAML code below, specify the source and destination paths.
[email protected] ~$ vi copy.yml --- - hosts: win tasks: - name: Copy File win_copy: src: C:output.pdf dest: C:ansible_examples remote_src: yes
Run ansible-playbook for win_copy.
[email protected] ~$ ansible-playbook copy.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Copy File] ***************************************************************************************************************************** changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
The file was successfully copied to the destination on the remote Windows system.
Install/Remove MSI
To install an application using an MSI file, you need to use win_get_url to specify the path to the MSI file to download, and then use the win_package module to install it. The present state means that the MSI will be installed on the machine and the application is in the current state.
This is where I install Apache.
The YAML code used is:
[email protected] ~$ vi msi.yml --- - name: Installing Apache MSI hosts: win tasks: - name: Download the Apache installer win_get_url: url: https://archive.apache.org/dist/httpd/binaries/win32/httpd-2.2.25-win32-x86-no_ssl.msi dest: C:ansible_exampleshttpd-2.2.25-win32-x86-no_ssl.msi - name: Install MSI win_package: path: C:ansible_exampleshttpd-2.2.25-win32-x86-no_ssl.msi state: present
Run ansible-playbook to install with MSI.
[email protected] ~$ ansible-playbook msi.yml PLAY [Installing Apache MSI] ***************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Download the Apache installer] ********************************************************************************************************* changed: [192.168.0.102] TASK [Install MSI] *************************************************************************************************************************** changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now go to Windows system and check if Apache application is installed successfully.
C:Userstoadmin.ru>cd C:Program Files (x86)Apache Software FoundationApache2.2binC:Program Files (x86)Apache Software FoundationApache2.2bin>httpd -v Server version: Apache/2.2.25 (Win32) Server built: Jul 10 2013 01:52:12
You can also install applications using the MSI with arguments. Below is the same example as above, but instead of a state, we use the install argument to install apache.
The YAML code used is:
---- name: Installing Apache MSI hosts: win tasks: - name: Download the Apache installer win_get_url: url: https://archive.apache.org/dist/httpd/binaries/win32/httpd-2.2.25-win32-x86-no_ssl.msi dest: C:ansible_exampleshttpd-2.2.25-win32-x86-no_ssl.msi - name: Install MSI win_package: path: C:ansible_exampleshttpd-2.2.25-win32-x86-no_ssl.msi arguments: - /install - /passive - /norestart
To uninstall an application using an MSI file, you need to use the win_package module. The "missing" status means that the application will be uninstalled using the MSI file.
Here I remove Apache.
[email protected] ~$ vi uninstall_msi.yml --- - name: UnInstalling Apache MSI hosts: win tasks: - name: UnInstall MSI win_package: path: C:ansible_exampleshttpd-2.2.25-win32-x86-no_ssl.msi state: absent
Run ansible-playbook to uninstall with MSI.
[email protected] ~$ ansible-playbook uninstall_msi.yml PLAY [UnInstalling Apache MSI] ***************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [UnInstall MSI] ************************************************************************************************************************* changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now if I check the apache version I get the below output as the application has been uninstalled.
C:Program Files (x86)Apache Software FoundationApache2.2bin>httpd -v 'httpd' is not recognized as an internal or external command,operable program or batch file.
Software removal (.EXE)
You can also uninstall the software using an .exe file using the product ID of that software.
[email protected] ~$ vi uninstall.yml --- - hosts: win tasks: - name: Uninstall 7-Zip from the exe win_package: path: C:Program Files7-ZipUninstall.exe product_id: 7-Zip arguments: /S state: absent
Run ansible-playbook to remove 7-Zip.
[email protected] ~$ ansible-playbook uninstall.yml PLAY [win] ************************************************************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************************************************* ok: [192.168.0.102] TASK [Uninstall 7-Zip from the exe] *********************************************************************************************************************************************************** changed: [192.168.0.102] PLAY RECAP ************************************************************************************************************************************************************************************* 192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Stop/Start/Restart Windows Services
The available win_service module is used to start, stop, or restart a service. Here I will show you how to stop the tomcat service.
You need to provide the service name in the YAML file and set the stop state.
[email protected] ~$ vi service.yml --- - hosts: win tasks: - name: Stop service Tomcat win_service: name: Tomcat8 state: stopped
Run ansible-playbook to stop the tomcat service.
[email protected] ~$ ansible-playbook service.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Stop service Tomcat] **************************************************************************************************************** changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If you check the tomcat service on a Windows system, it is currently in a stopped state.
You can define a state to start, restart, or pause to change the state of a service.
Fact gathering
Using the win_disk_facts add-on module, you can get all information about the target host's disk.
[email protected] ~$ vi disk.yml --- - hosts: win tasks: - name: Get disk facts win_disk_facts: - name: Output first disk size debug: var: ansible_facts.disks[0].size - name: Convert first system disk into various formats debug: msg: '{{ disksize_gib }} vs {{ disksize_gib_human }}' vars: # Get first system disk disk: '{{ ansible_facts.disks|selectattr("system_disk")|first }}' # Show disk size in Gibibytes disksize_gib_human: '{{ disk.size|filesizeformat(true) }}' disksize_gib: '{{ (disk.size/1024|pow(3))|round|int }} GiB'
Run ansible-playbook to get disk information.
[email protected] ~$ ansible-playbook disk.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Get disk facts] ************************************************************************************************************************ ok: [192.168.0.102] TASK [Output first disk size] **************************************************************************************************************** ok: [192.168.0.102] => { "ansible_facts.disks[0].size": "1000204886016" } TASK [Convert first system disk into various formats] **************************************************************************************** ok: [192.168.0.102] => { "msg": "932 GiB vs 931.5 GiB" } PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Using the ansible win_command module, you can execute commands on a remote host and get processor information, device information, and more.
[email protected] ~$ vi check.yml --- - hosts: win tasks: - name: Get disk facts win_command: wmic cpu get caption, deviceid, name, numberofcores, maxclockspeed, status register: usage - debug: msg="{{ usage.stdout }}"
Run ansible-playbook to get information about the remote system.
[email protected] ~$ ansible-playbook check.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Get facts] ************************************************************************************************************************ changed: [192.168.0.102] TASK [debug] ********************************************************************************************************************************* ok: [192.168.0.102] => { "msg": "Caption DeviceID MaxClockSpeed Name NumberOfCores Status rrnIntel64 Family 6 Model 142 Stepping 9 CPU0 2712 Intel(R) Core(TM) i5-7200U CPU @ 2.50GHz 2 OK rrnrrn" } PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Running commands
Whatever commands you run in the window, they can be run through the ansible win_command module. You just need to specify the command in your YAML file. Here I'm just creating a directory.
[email protected] ~$ vi commands.yml --- - hosts: win tasks: - name: run an executable using win_command win_command: whoami.exe - name: run a cmd command win_command: cmd.exe /c mkdir C:test
Run ansible-playbook to execute the win_command operation.
[email protected] ~$ ansible-playbook commands.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [run an executable using win_command] *************************************************************************************************** changed: [192.168.0.102] TASK [run a cmd command] ********************************************************************************************************************* changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Environment Variables
The Windows system has several environment variables, such as JAVA_HOME. Using the ansible win_environment module, you can add or change environment variables on a Windows system. In this example, I'm adding a new variable to the list of Windows environment variables.
[email protected] ~$ vi env.yml --- - hosts: win tasks: - name: Set an environment variable for all users win_environment: state: present name: NewVariable value: New Value level: machine
Run ansible-playbook to add an environment variable to the remote windows machine.
[email protected] ~$ ansible-playbook env.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Set an environment variable for all users] ********************************************************************************************* changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Go to the environment variables window; you will see that the new variable you just added is there.
Add/Edit Registry
The available win_regedit module is used to add or edit registry data on a remote Windows machine. You need to specify the path to the registry and the content to be added/updated. Here I create a new registry entry toadmin.ru inside the HKLM:SOFTWARE path and then add the name and data to this registry.
[email protected] ~$ vi registry.yml --- - hosts: win tasks: - name: Creating a registry win_regedit: path: HKLM:SOFTWAREtoadmin.ru - name: Modifying a registry, adding name and data win_regedit: path: HKLM:SOFTWAREtoadmin.ru name: Geek data: Flare
Run ansible-playbook to add the registry.
[email protected] ~$ ansible-playbook registry.yml PLAY [win] *********************************************************************************************************************************** TASK [Gathering Facts] *********************************************************************************************************************** ok: [192.168.0.102] TASK [Creating a registry] ******************************************************************************************************************* changed: [192.168.0.102] TASK [Modifying a registry, adding name and data] ******************************************************************************************** changed: [192.168.0.102] PLAY RECAP *********************************************************************************************************************************** 192.168.0.102 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
If you go to the Registry Editor on the remote system, you will see that this registry has been successfully added with the Name and Data parameters.
Delete log
The optional win_eventlog module is used to add, clear, or remove Windows event logs from a Windows system.
Go to Windows Powershell and list the event logs present on the remote Windows machine.
PS C:Userstoadmin.ru> Get-EventLog -ListMax(K) Retain OverflowAction Entries Log ------ ------ -------------- ------- --- 20,480 0 OverwriteAsNeeded 33,549 Application 20,480 0 OverwriteAsNeeded 0 HardwareEvents 512 7 OverwriteOlder 20 Internet Explorer 20,480 0 OverwriteAsNeeded 0 Key Management Service 128 0 OverwriteAsNeeded 190 OAlerts Security 20,480 0 OverwriteAsNeeded 44,828 System 15,360 0 OverwriteAsNeeded 3,662 Windows PowerShell
Now I will show you how to remove logs from all sources for Internet Explorer.
[email protected] ~$ vi log.yml --- - hosts: win tasks: - name: Remove Internet Explorer Logs win_eventlog: name: Internet Explorer state: absent
Run ansible-playbook to uninstall Internet Explorer from a remote Windows machine.
[email protected] ~$ ansible-playbook log.yml PLAY [win] ************************************************************************************************************************************************************************************* TASK [Gathering Facts] ************************************************************************************************************************************************************************* ok: [192.168.0.102] TASK [Remove Internet Explorer Logs] ********************************************************************************************************************************************** changed: [192.168.0.102] PLAY RECAP ************************************************************************************************************************************************************************************* 192.168.0.102 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Now if you list the event logs again, you will see that the Internet Explorer logs have been removed.
PS C:Userstoadmin.ru> Get-EventLog -ListMax(K) Retain OverflowAction Entries Log ------ ------ -------------- ------- --- 20,480 0 OverwriteAsNeeded 33,549 Application 20,480 0 OverwriteAsNeeded 0 HardwareEvents 20,480 0 OverwriteAsNeeded 0 Key Management Service 128 0 OverwriteAsNeeded 190 OAlerts Security 20,480 0 OverwriteAsNeeded 44,835 System 15,360 0 OverwriteAsNeeded 56 Windows PowerShell
So, that's all for the Ansible playbooks that can be used to remotely administer Windows. Go ahead and try these playbooks. You can also try other Ansible Modules for Windows available.