Windows Automation with Polycrate: Ansible and WinRM Without Pain
Fabian Peter 11 Minuten Lesezeit

Windows Automation with Polycrate: Ansible and WinRM Without Pain

Automate Windows servers with Ansible and Polycrate via WinRM
Ganze Serie lesen (24 Artikel)

Diese Serie zeigt Schritt für Schritt, wie Ansible mit Polycrate zu einer strukturierten, teilbaren und compliance-fähigen Automatisierungsplattform wird – von den Grundlagen bis zu Enterprise-Szenarien.

  1. Install Polycrate and Build Your First Ansible Block in 15 Minutes
  2. Blocks, Actions, and Workspaces: The Modular Principle of Polycrate
  3. Linux Servers on Autopilot: System Management with Polycrate and Ansible
  4. Nginx and Let's Encrypt as a Reusable Polycrate Block
  5. Managing Docker Stacks on Linux Servers with Polycrate
  6. Many Servers, One Truth: Multi-Server Management with Polycrate Inventories
  7. Windows Automation with Polycrate: Ansible and WinRM Without Pain
  8. Windows Software Deployment without SCCM: Chocolatey and Ansible
  9. Hybrid Automation: Windows and Linux in the Same Polycrate Workspace
  10. Deploy Kubernetes Apps from the PolyHub: From Idea to Deployment in Minutes
  11. Creating Your Own Kubernetes App as a Polycrate Block: A Step-by-Step Guide
  12. Multi-Cluster Kubernetes with Polycrate: Why One Cluster, One Workspace
  13. SSH Sessions and kubectl Debugging: Polycrate as an Operations Tool
  14. Helm Charts as a Polycrate Block: More Control Over Chart Deployments
  15. Policy as Code: Automating Compliance Requirements with Polycrate
  16. Workspace Encryption: Managing Secrets in GDPR Compliance – Without External Tooling
  17. Managing Raspberry Pi and Edge Nodes with Polycrate in IoT and Edge Computing
  18. Enterprise Automation: Building, Versioning, and Sharing Blocks Within Teams
  19. Polycrate MCP: Connecting AI Assistants with Live Infrastructure Context
  20. Polycrate vs. plain Ansible: What You Gain – and Why It's Worth It
  21. The Polycrate Ecosystem: PolyHub, API, MCP, and the Future of Automation
  22. Your First Productive Polycrate Workspace: A Checklist for Getting Started
  23. Auditable Operations: SSH Sessions and CLI Activities with Polycrate API
  24. Polycrate API for Teams: Centralized Monitoring and Remote Triggering

TL;DR

  • Set up WinRM properly once with HTTPS, certificate, and firewall rules, and you’ll have a stable foundation for Ansible automation on Windows servers.
  • With Polycrate, Ansible runs with all WinRM and Python dependencies in a container—no pywinrm chaos, no local installations, no version debates within the team.
  • Windows automation is already built into the Polycrate Ansible image: including the ansible.windows collection (e.g. win_service, win_updates), pywinrm, and the matching Ansible bundle—no custom Dockerfile, no manual ansible-galaxy installs for typical use. You only configure the workspace, inventory, and playbooks.
  • A dedicated Polycrate block for Windows forms your reusable “Windows toolbox”: manage services, install features, adjust the registry, distribute software, apply patches—all as clearly structured actions.
  • Passwords and other secrets are stored in secrets.poly and secured via built-in workspace encryption with age—not in inventory.yml.
  • ayedo supports Windows teams with practical automation blueprints, Polycrate implementation, and a focused Windows automation workshop—from WinRM basics to scalable patch management.

Why Windows Admins Should Consider Polycrate + Ansible

Many Windows admins view Ansible skeptically:

  • “That’s a Linux tool.”
  • “Setting up WinRM is annoying.”
  • “Python, pywinrm, OpenSSL—I don’t want to deal with all that locally.”

Technically, Ansible is an excellent tool, especially for Windows:

  • There are dedicated collections like ansible.windows and community.windows.
  • You can manage services, roles/features, registry, software, and patches idempotently.
  • You get clean, traceable changes with playbooks that are easy to version.

What hurts in practice is something else:

  1. Dependency Problem:
    Maintaining the same Python/Ansible/WinRM versions on every admin laptop and jump box is exhausting—and security-sensitive.

  2. Playbook Proliferation:
    Five different script folders, slightly different playbooks, no one knows what’s “official.”

  3. Secrets Everywhere:
    Passwords in inventory.yml, in group_vars, in scripts—and then comes the audit.

Polycrate addresses these issues:

  • The bundled image ships Ansible for Windows with ansible.windows and pywinrm—Windows modules are not an add-on you install separately; they are part of the default toolchain. For typical ansible.windows.* playbooks you need no extra Dockerfile.poly and no manual ansible-galaxy collection install ansible.windows. Only if you need additional collections do you extend the image (e.g. community.windows).
  • Ansible always runs in a container—identical on every machine.
  • Your automation is structured into blocks that you can share locally or via an OCI registry and PolyHub.
  • Workspace encryption with age ensures you can securely store passwords in secrets.poly without an extra vault solution.

In this post, we’ll build this step by step—with a focus on Windows admins without cloud-native experience.


Set Up WinRM Correctly: HTTPS, Certificate, Firewall

Before Ansible can communicate with your Windows servers via Polycrate, WinRM must be properly configured. We focus on:

  • HTTPS (Port 5986)
  • Certificate (Self-Signed or from your PKI)
  • Firewall allowance
  • Authentication with NTLM

Step 1: Enable WinRM Service

On the target server (e.g., Windows Server 2022), open PowerShell as Administrator:

winrm quickconfig

If the service is not running, you will be asked if it should be configured. Confirm this.

This usually sets up an HTTP listener on port 5985. For Ansible over the internet or in sensitive networks, you should disable HTTP and use HTTPS.

Step 2: Create or Assign a Certificate for HTTPS

For testing and small environments, a self-signed certificate is sufficient. In a domain, you should use a certificate from your corporate PKI.

Self-Signed Example:

$newCert = New-SelfSignedCertificate `
  -DnsName "win01.acme-corp.com" `
  -CertStoreLocation "Cert:\LocalMachine\My"

Note the thumbprint:

$newCert.Thumbprint

In production environments, replace this step with a server certificate issued by your CA.

Step 3: Configure HTTPS Listener for WinRM

First, check existing HTTP listeners:

winrm enumerate winrm/config/Listener

Create an HTTPS listener with your certificate (insert thumbprint):

$thumb = "<YOUR_THUMBPRINT>"

winrm create winrm/config/Listener?Address=*+Transport=HTTPS `
"@{Hostname=`"win01.acme-corp.com`"; CertificateThumbprint=`"$thumb`"}"

If an HTTPS listener already exists, you can alternatively adjust it with winrm set.

Check security settings:

winrm get winrm/config

Important points:

  • AllowUnencrypted should be false.
  • Under Service/Auth, Basic should ideally be false, NTLM/Kerberos are preferable.

Step 4: Open Firewall for WinRM HTTPS

The standard port for WinRM over HTTPS is 5986. Open the port in the Windows Firewall:

New-NetFirewallRule `
  -Name "WINRM_HTTPS_IN" `
  -DisplayName "WinRM over HTTPS" `
  -Protocol TCP `
  -LocalPort 5986 `
  -Direction Inbound `
  -Action Allow

Depending on the environment, you can restrict access to certain subnets or management servers.

Step 5: Test Connection from a Client

From an admin machine (or a jump box), you can test if HTTPS works with PowerShell:

Test-WsMan win01.acme-corp.com -UseSSL

If this works, the technical foundations for Ansible are in place. With plain Ansible, you would now install Python, Ansible, pywinrm, and SSL libraries and configure them accordingly.

With Polycrate, you skip this part entirely—bringing us to the workspace.


Polycrate Workspace for Windows Hosts

We create a simple Polycrate workspace that manages your Windows servers.

workspace.poly with Windows Block

In the root directory of your workspace is the workspace.poly:

name: acme-corp-automation
organization: acme

blocks:
  - name: windows-baseline
    from: windows-baseline
    config:
      windows_group: "windows"

What’s happening here:

  • name: The name of your workspace, e.g., your team or project.
  • blocks: List of block instances. We have a block windows-baseline that comes from a local directory ./blocks/windows-baseline.
  • config.windows_group: The host group this block refers to by default.

More about workspaces can be found in the Workspace Documentation.

inventory.yml for Windows

Directly in the workspace root is inventory.yml. As in Multi-server management with Ansible inventories, all hosts live under all.hosts; under children, the windows group references them by name only—shared WinRM settings go in the group vars (no per-host duplication):

all:
  hosts:
    win01.acme-corp.com: {}
    win02.acme-corp.com: {}

  children:
    windows:
      hosts:
        win01.acme-corp.com:
        win02.acme-corp.com:
      vars:
        ansible_connection: winrm
        ansible_winrm_transport: ntlm
        ansible_port: 5986
        ansible_winrm_server_cert_validation: ignore

Important:

  • ansible_connection: winrm tells Ansible to use WinRM.
  • ansible_winrm_transport: ntlm chooses NTLM as the auth method (suitable for many classic Windows environments).
  • ansible_winrm_server_cert_validation: ignore is useful for self-signed certificates. In production environments, you should validate certificates correctly.

No passwords in the inventory. They will be placed in secrets.poly.

Further details on Ansible integration can be found in the Ansible Documentation for Polycrate.


Secrets for Windows: Passwords in secrets.poly Instead of inventory.yml

Polycrate comes with workspace encryption with age built-in. You don’t need to run an external vault tool to securely store passwords.

Create secrets.poly

In the workspace root, create a file secrets.poly:

win_admin_user: "acme-admin"
win_admin_password: "SuperSecurePassword123!"

Before you commit this file to Git, encrypt the workspace:

polycrate workspace encrypt

Details can be found in the Workspace Encryption Documentation.

Polycrate makes these secrets available in the playbook as workspace.secrets.*. We’ll use this to set ansible_user and ansible_password—without storing them in the inventory.


The Windows Block: Structured Automation Instead of Playbook Proliferation

Now we define our Windows block. The directory ./blocks/windows-baseline contains at least:

  • block.poly
  • baseline.yml (Windows base configuration)
  • patches.yml (Windows patch management)

block.poly for Windows

name: windows-baseline
version: 0.1.0
kind: generic

config:
  windows_group: "windows"

actions:
  - name: baseline
    description: "Windows base configuration (services, features, registry, software)"
    playbook: baseline.yml

  - name: patches
    description: "Windows patch management with win_updates"
    playbook: patches.yml
  • kind: generic is suitable for classic Ansible blocks.
  • Under actions, you define descriptive actions, each executing a playbook.
  • With config.windows_group, you can centrally control the target group.

Best practices for blocks can be found in the Block Best Practices and the Blocks Documentation.

Execute Actions

You always execute an action with the same schema:

polycrate run windows-baseline baseline

or:

polycrate run windows-baseline patches

Polycrate starts a container with your defined toolchain, loads the workspace including encrypted secrets, and runs Ansible within it. You do not need to have Ansible, Python, or pywinrm installed on your laptop.


Automate Initial Windows Tasks: Services, Features, Registry, Software

Now it gets concrete: We write the playbook baseline.yml and use modules from ansible.windows and community.windows.

baseline.yml: Windows Base Configuration

- name: Apply Windows Baseline
  hosts: "{{ block.config.windows_group }}"
  gather_facts: false

  vars:
    ansible_user: "{{ workspace.secrets.win_admin_user }}"
    ansible_password: "{{ workspace.secrets.win_admin_password }}"
    ansible_connection: winrm
    ansible_winrm_transport: ntlm
    ansible_port: 5986
    ansible_winrm_server_cert_validation: ignore

  tasks:
    - name: Ensure 'Spooler' service is running
      ansible.windows.win_service:
        name: Spooler
        start_mode: auto
        state: started

    - name: Install 'Web-Server' (IIS) feature
      ansible.windows.win_feature:
        name: Web-Server
        state: present
        include_sub_features: true
        restart: false

    - name: Allow Remote Desktop via registry key
      ansible.windows.win_regedit:
        path: HKLM:\System\CurrentControlSet\Control\Terminal Server
        name: fDenyTSConnections
        data: 0
        type: dword

    - name: Install Chocolatey (if not present)
      ansible.windows.win_chocolatey:
        state: present

    - name: Install 7zip via Chocolatey
      ansible.windows.win_chocolatey:
        name: 7zip
        state: present

    - name: Install custom MSI package
      ansible.windows.win_package:
        path: "\\fileserver.acme-corp.com\software\MyApp.msi"
        product_id: "{12345678-ABCD-1234-ABCD-1234567890AB}"
        state: present

What’s happening here:

  • hosts: We use the group from block.config.windows_group, i.e., windows. This way, you can use the same block in another workspace with a different group.
  • vars: We set connection parameters (user/password, WinRM details) from workspace.secrets.*. That is the core idea: no plaintext passwords in the inventory.
  • ansible.windows.win_service: The “Spooler” service must be running and set to start automatically. The module belongs to ansible.windows (not ansible-core); it is already included in the default Polycrate image (see TL;DR and “Polycrate addresses these issues”).
  • ansible.windows.win_feature: Installs the IIS role including subfeatures.
  • ansible.windows.win_regedit: Enables Remote Desktop (classic example).
  • ansible.windows.win_chocolatey: Installs Chocolatey and then a package.
  • ansible.windows.win_package: Installs an MSI from a central share.

You would write a similar playbook with plain Ansible—Ansible is fine here. The difference is everything around it:

  • You would have to provide ansible.windows and community.windows locally.
  • Install pywinrm and SSL dependencies cleanly.
  • Make sure every admin has the same environment.

With Polycrate, all of that ships in the bundled Ansible container (see python-requirements.txt / Polycrate Dockerfile: ansible bundle, pywinrm, additional Galaxy collections). Only if you need more collections do you extend the image (e.g. Dockerfile.poly). Your colleagues only need Polycrate and Docker—no local Python tuning.


Windows patch management with win_updates and reboot handling

Patches are a typical use case Windows admins want to automate cleanly—including controlled reboots.

patches.yml: install updates by category

- name: Install Windows patches
  hosts: "{{ block.config.windows_group }}"
  gather_facts: false

  vars:
    ansible_user: "{{ workspace.secrets.win_admin_user }}"
    ansible_password: "{{ workspace.secrets.win_admin_password }}"
    ansible_connection: winrm
    ansible_winrm_transport: ntlm
    ansible_port: 5986
    ansible_winrm_server_cert_validation: ignore

  tasks:
    - name: Install security and critical updates
      ansible.windows.win_updates:
        category_names:
          - SecurityUpdates
          - CriticalUpdates
        state: installed
        reboot: yes
      register: update_result

    - name: Reboot if required
      ansible.windows.win_reboot:
        msg: "Rebooting for Windows updates."
        pre_reboot_delay: 60
        post_reboot_delay: 120
      when: update_result.reboot_required

Explanation:

  • ansible.windows.win_updates controls which updates to install; category_names lets you filter.
  • reboot: yes allows win_updates to initiate a reboot if needed.
  • ansible.windows.win_reboot handles the reboot in the Ansible context and waits until the host is reachable again.

From a Windows admin’s perspective, this is where Ansible shines: you can build a reproducible patch playbook and roll it out monthly via a Polycrate workflow, for example.

More on workflows: Workflows documentation.


Compared to plain Ansible: what Polycrate removes

Imagine building the same setup with plain Ansible—without Polycrate:

  1. On your admin laptop:

    • Install Python in a suitable version.
    • Install Ansible (e.g. via pip or the package manager).
    • Install pywinrm and requests-ntlm.
    • Install ansible.windows and community.windows collections.
    • Adjust ansible.cfg (inventory path, WinRM defaults, etc.).
  2. On your colleagues’ laptops:

    • The same setup—as identical as possible.
    • Coordinate updates regularly to avoid version drift.
  3. In documentation:

    • Maintain install guides (“Please install Python 3.11.2, then pip install …”).
    • Answer audit questions about supply-chain risk (“Who reviews PyPI packages?”).

With Polycrate, the picture changes:

  • Ansible, pywinrm, collections, etc. live in a container image.
  • You define the toolchain once (e.g. via Dockerfile.poly) and share it with the team.
  • Polycrate starts the container, mounts your workspace, and runs actions.

The block model adds structure:

  • Instead of loose playbooks on disk, you have a Windows block with clearly named actions (baseline, patches).
  • You can share that block via an OCI registry—internally or through PolyHub.
  • Other teams can consume your block without copying your entire workspace.

Technical details: Registry documentation and PolyHub.


Frequently asked questions

Does this only work with domain-joined servers?

No. Ansible over WinRM with ansible_connection: winrm and ansible_winrm_transport: ntlm also works for workgroup servers, as long as:

  • name resolution is correct (DNS or hosts file),
  • you have valid local or domain credentials,
  • firewall rules allow WinRM access.

In a domain you can additionally use Kerberos, which is often preferable. For getting started, NTLM is often simpler, especially in mixed environments.

How do I handle different administrator accounts per server?

You have several options:

  • Set different users per host in inventory.yml and only pull the password from secrets.poly.
  • Store multiple credentials in secrets.poly (e.g. win_admin_user_dmz, win_admin_user_internal) and use block.config in the block to choose which account to use.
  • Define entirely different playbooks/blocks for especially sensitive systems.

Polycrate gives you enough flexibility with workspace.secrets.* and block.config.* without scattering passwords in plaintext files. See best practices.

We already use Ansible—is Polycrate still worth it?

If you already have a working Ansible setup, Polycrate mainly adds:

  • Standardized toolchain: no more debates about who installed which Python/Ansible version.
  • Structure through blocks: wrap existing playbooks in clear actions that non-specialists can run safely.
  • Built-in encryption: secrets in secrets.poly and encrypted workspace directories without extra tools.

For many teams, the first step is lift-and-shift of existing playbooks into a block and clean up gradually. We describe migration paths in other posts in this series.

More questions? See our FAQ.


Putting it into practice

What did we cover in this post?

  • How to set up WinRM on Windows servers once, with HTTPS, certificate, and firewall rules.
  • How a Polycrate workspace is built with inventory.yml, workspace.poly, secrets.poly, and a Windows block (block.poly).
  • How to write Ansible playbooks that use ansible.windows and community.windows to manage services, features, registry, software, and updates—without a local Ansible install.
  • How to use Polycrate’s built-in security: workspace encryption with age and secrets in secrets.poly instead of inventory.yml.

For Windows teams, this is often where automation turns from “occasional scripts” into a repeatable, shareable, auditable platform.


How ayedo can help

We regularly help teams with setups like this:

  • We develop Windows-specific blocks with you (e.g. baseline hardening, role-specific configuration, patch workflows).
  • We help migrate existing scripts and playbooks into clean Polycrate blocks.
  • We support integration with your processes—change management, compliance, and more.

If you want a practical, hands-on introduction with your team, our Windows automation workshop covers WinRM basics through scalable patch management with Polycrate.

Ähnliche Artikel