Configure Ansible to access Windows Servers:
- If you have not yet installed Ansible, check Install and configure ansible on Ubuntu server
- After installing Ansible, let us configure it to access Windows servers. Hoping that Windows server is already configured with WinRM.
- Install PIP if not installed already.
sudo apt install python3-pip
- Install WinRM module on Ansible server
sudo pip3 install "pywinrm>=0.3.0"
- You may receive a message if modult is already installed that Requirement already satisfied: pywinrm>=0.3.0 in /usr/lib/python3/dist-packages (0.3.0)
- Now edit hosts file with Windows hosts and Variables
nano inventory
If you have not yet installed Ansible, check Install and configure ansible on Ubuntu server - After installing Ansible, let us configure it to access Windows servers. Hoping that Windows server is already configured with WinRM.
- Install PIP if not installed already.
sudo apt install python3-pip
- Install WinRM module on Ansible server
sudo pip3 install "pywinrm>=0.3.0"
- You may receive a message if modult is already installed that Requirement already satisfied: pywinrm>=0.3.0 in /usr/lib/python3/dist-packages (0.3.0)
- Now edit hosts file with Windows hosts and Variables
nano inventory
[windows]
172.16.1.101
172.16.1.111
[windows:vars]
ansible_user=winadmin\wintel
ansible_password=P@ssw0rd
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_port=5985
*** Please do not give password in Production environment. You can use ansible-vault to encrypt the inventory file. Note that the above example uses NTLM method to authenticate. You should use Kerberos in production. And make sure that port 5985 is opened on Windows servers. Now test connectivity to windows servers
ansible windows -i inventory -m win_ping
172.16.1.101 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.111 | SUCCESS => {
"changed": false,
"ping": "pong"
}
You can use FQDN in place of IP values of servers. If you configured WinRM with a certificate, add the following line to inventory file.
ansible_winrm_cert_validation=ignore This is not recommended in production environment. Instead, you configure certificate from a certificate server. The above will work for NTLM authentication. Let us configure with Kerberos authentication. Install and Setup Kerberos
sudo apt install python3-dev libkrb5-dev krb5-user



Once the dependencies have been installed, the python-kerberos wrapper can be install using pip:
sudo pip3 install pywinrm[kerberos]
Check kerberos configuration file if the required values are set correctly. If the values are not correct, you can modify manually.
sudo nano /etc/krb5.conf
[libdefaults]
default_realm = WINADMIN.LOCAL
[realms]
WINADMIN.LOCAL = { kdc = 172.16.1.101 admin_server = 172.16.1.101 }
Check if the kerberos is working.
winadmin@ansible02:~$ kinit wintel@WINADMIN.LOCAL
Password for wintel@WINADMIN.LOCAL:
winadmin@ansible02:~$ klist
Ticket cache: FILE:/tmp/krb5cc_1000
Default principal: wintel@WINADMIN.LOCAL
Valid starting Expires Service principal
09/12/2021 11:44:26 09/12/2021 21:44:26 krbtgt/WINADMIN.LOCAL@WINADMIN.LOCAL
renew until 09/13/2021 11:44:21
winadmin@ansible02:~$ kdestroy
We can see that kerberos ticket is generated and we destroyed later. Modify inventory file to use kerberos authentication.
nano inventory
[windows]
172.16.1.101
172.16.1.111
[windows:vars]
ansible_user=wintel@WINADMIN.LOCAL
ansible_password=P@ssw0rd
ansible_connection=winrm
ansible_winrm_transport=kerberos
ansible_port=5985
Observe that I have changed the values ansible_user and ansible_winrm_transport to wintel@WINADMIN.LOCAL and kerberos respectively. Port 5985 is not encrypted and so you need to configure a certificate to 5986 and use. If you still want to use 5985, just run the following PowerShell command on the windows server
Set-Item -Path WSMan:\localhost\Service\AllowUnencrypted -Value true
Test connectivity to windows servers using ansible.
ansible windows -i inventory -m win_ping
output:
winadmin@ansible02:~$ ansible windows -i inventory -m win_ping
172.16.1.111 | UNREACHABLE! => {
"changed": false,
"msg": "kerberos: Bad HTTP response returned from server. Code 500",
"unreachable": true
}
172.16.1.101 | SUCCESS => {
"changed": false,
"ping": "pong"
}
Connection to first server failed because I did not allow unencrypted communication.