How to Manage Windows Services with Ansible

ansible ansible for windows Mar 04, 2025
managing windows services with ansible

Service management is a pretty common task for both DBAs and Windows administrators.  If you're like me, you've spent countless hours remoting into servers just to check the status of a service or to manually restart it.  Perhaps you've needed to disable a service briefly while troubleshooting or change the password for the service account. 

Managing services this way can't scale and is prone to errors.

Today, I want to dive deeper into Ansible's win_service module (including examples).  It was number 11 on my "Essential Ansible Windows Modules Every Admin Should Know" list.  

Of course, you could use PowerShell for service management, too.  But, let's review why using Ansible's win_service module may offer several advantages that might make it a better choice for some administrators.

  • Idempotency - The win_service module performs idempotent operations, meaning actions like starting or stopping a service only run if necessary.  This ensures that the desired state is enforced without unnecessary repeated actions, making automation scripts more reliable and preventing unintended side effects.  Scripting with PowerShell might require additional logic to achieve the same level of idempotency.
  • Cross-Platform Compatibility - Ansible is cross-platform, allowing you to manage both Windows and Linux systems for a single platform.  PowerShell is primarily Windows-centric, so using Ansible can streamline automation across diverse environments.
  • Simplified Syntax - Ansible uses YAML, a human-readable language, which many find easier to learn and use compared to PowerShell scripting.
  • Logging built-in - Ansible reports, automatically, if a change was made or not.  In comparison, if you were to use PowerShell's get-service and set-service commands to start a service that is already running, you wouldn't get any information returned without writing a script to do so.

PowerShell is a very capable tool, but Ansible's win_service module offers features like idempotency and cross-platform compatibility, which can simplify service management and make it more efficient.

What is the win_service module?

The win_service module in Ansible is designed to manage and query Windows services. It lets you perform actions like starting, stopping, restarting, and configuring services on remote Windows machines. It's part of the ansible.windows collection and uses WinRM (Windows Remote Management) or SSH (Windows Server 2025) to communicate with target hosts.

Who benefits?

SQL Server DBAs and Windows Administrators can use the win_service module to automate daily tasks, improve efficiency, and reduce errors.

Common Problems Solved

  • Idempotency: Actions only run when necessary, preventing unintended side effects.
    • Ansible ensures that your automation scripts can be run multiple times without causing unintended side effects.
  • Service State Management: Comprehensive control to start, stop, restart, pause, or remove services.
  • Service Configuration: Configure startup type, dependencies, service user and passwords, and recovery options.
  • Remote Management: Manage services on remote Windows machines via WinRM or SSH, eliminating the need for direct access.

Use Cases and Examples

1. Starting and Stopping SQL Server Services

SQL Server DBAs can use Ansible to start or stop SQL Server services, including the database engine and SQL Server Agent.

For example, let's say you have an inventory file that contains a group of hosts named sqlservers.  You could ensure the database engine, for the default instance, was started using the playbook below.  If it's already running, nothing happens.

- hosts: sqlservers
  tasks:
    - name: Start SQL Server Database Engine
      ansible.windows.win_service:
        name: MSSQLSERVER
        state: started

This playbook targets a group of servers and starts the MSSQLSERVER service if it's not already running.  There are 3 managed hosts contained in this group.  Notice that only one reported a change (the service was running on the other two nodes, which reported ok or no change).

You could take this a step further and define the instance inside the inventory file as a variable.

Example:

[sqlservers]
SQL1.SANDBOX.LOCAL sql_instance_name="DEFAULT" sql_port=1433
SQL2.SANDBOX.LOCAL sql_instance_name="DEFAULT" sql_port=1433
SQL3.SANDBOX.LOCAL sql_instance_name="DEFAULT" sql_port=1433
SQL4.SANDBOX.LOCAL sql_instance_name="INSTA" sql_port=1433

Then, change the task to reference the sql_instance_name variable with a little Jinja2 magic (template expression).  If SQL_instance_name is "DEFAULT," then we'll substitute "MSSQLSERVER" as the service name; otherwise, if it's a named instance, we'll concatenate "MSSQL$" plus the instance name.  For example, SQL4 is a named instance, and the service name we're looking for is "MSSQL$INSTA."

- hosts: sqlservers
  tasks:
    - name: Start SQL Server Database Engine
      ansible.windows.win_service:
        name: "{% if 'DEFAULT' in sql_instance_name %}MSSQLSERVER{% else %}MSSQL${{ sql_instance_name }}{% endif %}"
        state: started

The same playbook can now be used to ensure the database engine is started for both default and named instances specified as the variable.  You can take this further and ensure the agent service is started as well.

2. Managing Windows Update Services

Windows Administrators can control the Windows Update service to automate updates or pause them during critical operations.

- hosts: windows_servers
  tasks:
    - name: Ensure Windows Update service is running
      ansible.windows.win_service:
        name: wuauserv
        state: started
        start_mode: auto

This playbook ensures the Windows Update service is running and set to start automatically. 

start_mode can be set to the following values:

  • auto 
  • delayed
  • disabled
  • manual

3. Configuring Failure Actions

Configure actions to be taken if a service fails, such as restarting the service.

- name: Configure service to restart after failure
  ansible.windows.win_service:
    name: MyService
    failure_actions:
      - type: restart
        delay: 60000 # Delay in milliseconds (1 minute)

4. Managing Service Dependencies

Ensure services start in the correct order by managing dependencies.

- name: Configure service dependencies
  ansible.windows.win_service:
    name: ServiceB
    dependencies:
      - ServiceA

This ensures ServiceA starts before ServiceB.

5. Changing Service Accounts

Control the user account under which a service runs.

- name: Change service account
  ansible.windows.win_service:
    name: MyService
    username: DOMAIN\service_account
    password: MySecretPassword

Advanced Tips

  • Security: Use Ansible Vault to encrypt sensitive information like passwords.  Or leverage managed or group-managed service accounts when possible.
  • Jinja2 template expression: Make your playbook more versatile by avoiding hard-coding service names.  This way, you can use the same playbook for multiple services.  

Conclusion

The win_service module is a versatile module for automating service management on Windows systems. Incorporating it into your Ansible playbooks can streamline tasks, improve efficiency, reduce errors, and ensure consistency.

Get free access to my "SQL Server Automation: Your First Steps with Ansible" Guide

Get started with Ansible using this free guide.  You'll discover how simple Ansible is to use, understand core concepts, and create two simple playbook examples.

When you signup, we'll send you periodic emails with additional free content.