Manage Windows Servers with Ansible

This is a follow-up to the previous post about automating Windows Server setup with unattended install.

Ansible can manage Windows versions under current support from Microsoft. Unlike Linux hosts that use SSH by default, Windows hosts are configured with WinRM.

WinRM Configuration

When connecting to a Windows server, there are a couple of different options that can be used for authentication.

  1. We will not use Basic authentication because it does not support HTTP encryption.
  2. We will not use NTLM authentication because it does not allow credential delegation.
  3. We can’t use Kerberos because we don’t have a domain environment. Our server uses local accounts.
  4. We will use CredSSP authentication that supports message encryption over HTTP and can be used for both local and domain accounts. Also, CredSSP allows credential delegation.

Open PowerShell as Administrator, and run the following commands:

$url = "https://raw.githubusercontent.com/ansible/ansible/devel/examples/scripts/ConfigureRemotingForAnsible.ps1"
$file = "$env:temp\ConfigureRemotingForAnsible.ps1"
(New-Object -TypeName System.Net.WebClient).DownloadFile($url, $file)
powershell.exe -ExecutionPolicy ByPass -File $file -DisableBasicAuth -EnableCredSSP

Verify that the Basic authentication is disabled, and that CredSSP is enabled.

AllowRemoteAccess and AllowRemoteShellAccess should be both set to true. AllowUnencrypted should be set to false.

winrm get winrm/config/Service
winrm get winrm/config/Winrs

Installation

Ansible uses the pywinrm package to communicate with Windows servers over WinRM. At the time of writing this, the package is not installed by default with the Ansible package. Install it manually (I’m using a Debian-based system here):

$ sudo apt install python-pip
$ pip install --ignore-installed pywinrm[credssp]

Ansible Configuration

The content of the file group_vars/windows can be seen below.

## It is suggested that these be encrypted with ansible-vault.
ansible_connection: winrm

## May also be passed on the command-line via --user
ansible_user: ansible

## May also be supplied at runtime with --ask-pass
ansible_password: PUT_YOUR_WINDOWS_PASSWORD_HERE

## Option for ansible_winrm_transport: basic|ntlm|credssp|kerberos
ansible_winrm_transport: credssp
ansible_port: 5986
ansible_winrm_scheme: https
ansible_winrm_server_cert_validation: ignore
ansible_winrm_operation_timeout_sec: 10
ansible_winrm_read_timeout_sec: 15
ansible_winrm_message_encryption: always

Ansible Playbook Examples to Manage Windows

Below are snippets from my playbooks that I use to manage Windows Servers. I hope that you will find them useful.

The ansible.windows collection includes the core Ansible plugins (e.g. win_user) to manage Windows hosts. You have to install it before you can use the plugins:

$ ansible-galaxy collection install ansible.windows

Examples:

- name: Windows | Create a user
  ansible.windows.win_user:
    name: SandyUser
    password: put_your_password_here_or_use_vault
    groups: Administrators
    update_password: on_create
    password_never_expires: yes
    user_cannot_change_password: no
    state: present
- name: Windows | Disable Administrator Account
  ansible.windows.win_user:
    name: Administrator
    state: present
    account_disabled: yes
- name: Windows | Download file from the Internet
  ansible.windows.win_get_url:
    url: "{{ web_url }}"
    dest: "{{ file_location }}"
    force: yes
- name: Windows | Create a directory
  ansible.windows.win_file:
    path: "C:/share"
    state: directory
- name: Windows | Create a public CIFS share
  ansible.windows.win_share:
    name: "share"
    description: Windows share
    path: "C:/share"
    list: yes
    full: Administrators
    read: Everyone
    state: present

The community.windows collection includes the community plugins (e.g. win_mapped_drive) to manage Windows hosts. You have to install it before you can use the plugins:

$ ansible-galaxy collection install community.windows

Examples:

- name: Windows | Firewall rules to allow inbound traffic
  community.windows.win_firewall_rule:
    name: HTTPS
    localport: 8443
    action: allow
    direction: in
    protocol: tcp
    state: present
    enabled: yes
- name: Windows | Create mapped drive with credentials and save the username and password
  block:
  - name: Windows | Save the network credentials required for the mapped drive
    community.windows.win_credential:
      name: server
      type: domain_password
      username: SandyUser
      secret: put_your_password_here_or_use_vault
      state: present

  - name: Windows | Create a mapped drive that requires authentication
    community.windows.win_mapped_drive:
      letter: S
      path: \\127.0.0.1\share
      state: present
  vars:
    # become is required to save and retrieve the credentials in the tasks
    ansible_become: yes
    ansible_become_method: runas
    ansible_become_user: '{{ ansible_user }}'
    ansible_become_pass: '{{ ansible_password }}'
- name: Windows | Install packages via Chocolatey
  win_chocolatey:
    name: firefox
    state: present

References

https://docs.ansible.com/ansible/latest/user_guide/windows_setup.html
https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html
https://docs.ansible.com/ansible/latest/user_guide/windows_usage.html

Leave a Reply

Your email address will not be published. Required fields are marked *