Si eres un sysadmin y administras servidores Windows, sabes que la vida puede ser… complicada. Reiniciar servicios manualmente, agregar usuarios a grupos, instalar software una y otra vez. ¿Y si te dijera que puedes automatizarlo todo con Ansible y tomarte un café tranquilo mientras el trabajo se hace solo?

En este artículo, te traigo una colección de playbooks de Ansible que te van a hacer la vida mucho más fácil. Desde instalar y desinstalar software hasta habilitar RDP, gestionar usuarios y más.

Antes de Empezar: ¿Por Qué Ansible en Windows?

Cuando pensamos en Ansible, lo primero que viene a la mente es Linux. Pero, sorpresa: Ansible también funciona de maravilla en Windows. 🚀

Ventajas de usar Ansible en Windows:

Automatización sin agentes: No necesitas instalar nada en los servidores Windows, solo activar WinRM o SSH.
Menos clics, más eficiencia: Olvídate de abrir gpedit.msc, services.msc y cmd cada cinco minutos.
Configuración consistente: Nada de “¿pero no lo configuré igual en el otro servidor?”.

Si no has configurado Ansible para Windows, lo primero que necesitas es habilitar WinRM en tus servidores. Aquí tienes una guía rápida para hacerlo:

# En PowerShell (ejecutar como administrador)
winrm quickconfig
winrm set winrm/config/service/Auth '@{Basic="true"}'
winrm set winrm/config/service '@{AllowUnencrypted="true"}'

O mejor aún, por SSH más seguro usando pares de claves siguiendo el vídeo y artículo:

Gestión de Usuarios en Windows con Ansible

Los usuarios vienen y van. Tu trabajo es asegurarte de que estén donde deben estar (o eliminarlos cuando ya no deberían estar). Vamos a ver cómo hacerlo con Ansible.

🔹 Crear un Usuario Local

---
- name: Crear un usuario local en Windows
  hosts: windows
  gather_facts: no
  vars:
    username: "usuario1"
    password: "P@ssw0rd123"

  tasks:
    - name: Crear el usuario en Windows
      ansible.windows.win_user:
        name: "{{ username }}"
        password: "{{ password }}"
        state: present
        description: "Usuario creado por No Solo Hacking dede Ansible"
        groups: [] # No lo añade a grupos en este playbook

🔹 Agregar un Usuario a los Administradores Locales y Escritorio Remoto

---
- name: Agregar usuario a Administradores locales en Windows
  hosts: windows
  gather_facts: no
  vars:
    username: "usuario1"
    group_name: "Administrators"  # Grupo de administradores locales en inglés
    group_name2: "Remote Desktop Users"  # Grupo de acceso escritorio remoto locales en inglés

  tasks:
    - name: Agregar usuario {{ username }} al grupo {{ group_name }}
      ansible.windows.win_group_membership:
        name: "{{ group_name }}"
        members:
          - "{{ username }}"
        state: present

    - name: Agregar usuario {{ username }} al grupo {{ group_name2 }}
      ansible.windows.win_group_membership:
        name: "{{ group_name2 }}"
        members:
          - "{{ username }}"
        state: present

🔹 Eliminar un Usuario

---
- name: Eliminar un usuario local en Windows
  hosts: windows
  gather_facts: no
  vars:
    username: "usuario1"

  tasks:
    - name: Borrar usuario {{ username }} de Windows
      ansible.windows.win_user:
        name: "{{ username }}"
        state: absent

🔹 Resetear la password de un usuario

---
- name: Generar y asignar una contraseña segura a usuario1 en Windows
  hosts: windows
  gather_facts: no

  tasks:
    - name: Generar contraseña aleatoria
      set_fact:
        random_password: >-
          {{
            lookup('community.general.random_string', length=6, upper=True, lower=True)
            ~ '-'
            ~ lookup('community.general.random_string', length=6, upper=True, lower=True)
            ~ lookup('community.general.random_string', length=1, special=True)
            ~ lookup('community.general.random_string', length=1, digits=True)
          }}

    - name: Mostrar la contraseña generada (solo para pruebas, eliminar en producción)
      debug:
        msg: "La contraseña generada es: {{ random_password }}"

    - name: Asignar la contraseña generada al usuario1
      ansible.windows.win_user:
        name: "usuario1"
        password: "{{ random_password }}"
        update_password: always
        password_never_expires: yes
        state: present
        account_disabled: yes

🔹 Resetear la password de un usuario basado en lista de palabras

---
- name: Generar y asignar una contraseña segura a usuario1 en Windows
  hosts: windows
  gather_facts: no

  tasks:
    - name: Lista de palabras para la contraseña
      set_fact:
        palabras:
          [
            "Lunes",
            "Rojo",
            "Dedo",
            "Casa",
            "Perro",
            "Gato",
            "Sol",
            "Cielo",
            "Reloj",
            "Silla",
            "Mesa",
            "Viento",
          ]

    - name: Generar palabras aleatorias
      set_fact:
        palabra1: "{{ palabras | random }}"
        palabra2: "{{ palabras | random }}"
        palabra3: "{{ palabras | random }}"

    - name: Generar número y carácter especial aleatorio
      set_fact:
        numero: "{{ lookup('community.general.random_string', length=1, digits=True) }}"
        caracter: "{{ lookup('community.general.random_string', length=1, special=True) }}"

    - name: Construir la contraseña final
      set_fact:
        random_password: "{{ palabra1 }} {{ palabra2 }} {{ palabra3 }} {{ numero }}{{ caracter }}"

    - name: Mostrar la contraseña generada (solo para pruebas, eliminar en producción)
      debug:
        msg: "La contraseña generada es: {{ random_password }}"

    - name: Asignar la contraseña generada al usuario1
      ansible.windows.win_user:
        name: "usuario1"
        password: "{{ random_password }}"
        update_password: always
        password_never_expires: yes
        state: present
        account_disabled: yes

📦 Instalación y Desinstalación de Software en Windows

Cada vez que necesitas instalar un programa en 10+ servidores, sabes que la opción manual es un infierno. 😰 Vamos a solucionarlo con Ansible.

🔹 Descargar e Instalar Software con un EXE (Ejemplo: Google Chrome)

---
- name: Descargar e instalar Google Chrome
  hosts: windows
  gather_facts: no
  vars:
    installer_url: "https://dl.google.com/chrome/install/latest/chrome_installer.exe"
    installer_path: "C:\\Instaladores\\chrome_installer.exe"

  tasks:
    - name: Descargar instalador de Chrome
      ansible.windows.win_get_url:
        url: "{{ installer_url }}"
        dest: "{{ installer_path }}"

    - name: Instalar Chrome
      ansible.windows.win_package:
        path: "{{ installer_path }}"
        state: present
        arguments: "/silent /install"

🔹 Descargar e Instalar Software con un MSI (Ejemplo: 7-Zip)

#Instala MSI
---
- name: Installa 7-Zip
  hosts: windows
  tasks:
    - name: Descargar 7-Zip
      win_get_url:
        url: https://www.7-zip.org/a/7z2409-x64.msi
        dest: C:\users\administrator\downloads\7zip.msi

    - name: Instalar 7-Zip
      win_package:
        path: C:\users\administrator\downloads\7zip.msi
        state: present
        arguments: "/quiet /norestart"

🔹 Desinstalar Software Sin Necesitar el MSI Original

---
- name: Desinstalar un programa usando el Product ID (GUID)
  hosts: windows
  gather_facts: no
  vars:
    product_id: "{4DC8B4CA-1F23-4FE8-9F0D-3F09C7990E69}" # Reemplaza con el GUID real

  tasks:
    - name: Desinstalar el programa
      ansible.windows.win_package:
        product_id: "{{ product_id }}"
        state: absent

🔹 Lista el software instlaado en Windows para obtener el ID y poder desisntalarlo

#lista software

---
- name: Obtener IdentifyingNumber de una aplicación específica
  hosts: windows
  gather_facts: no
  vars:
    app_name: "*7-zip*"  # Cambia esto al nombre de la aplicación que buscas

  tasks:

    - name: Buscar IdentifyingNumber de la aplicación {{ app_name }}
      ansible.windows.win_shell: |
        $app = Get-WmiObject Win32_Product | Where-Object { $_.Name -like "{{ app_name }}" }
        if ($app) { $app | Select-Object Name, IdentifyingNumber | ConvertTo-Json -Depth 2 } else { '[]' }
      register: app_info

    - name: Verificar si la aplicación fue encontrada
      set_fact:
        app_data: "{{ app_info.stdout | default('[]') | from_json }}"

    - name: Mostrar IdentifyingNumber si la aplicación existe
      debug:
        msg: "{{ app_data }}"
      when: app_data != []

    - name: Mostrar mensaje si la aplicación no fue encontrada
      debug:
        msg: "Aplicación '{{ app_name }}' no encontrada"
      when: app_data == []

🔄 Gestión de Servicios en Windows

¿Un servicio que se detiene en medio de la noche? Pesadilla. Vamos a ver cómo reiniciar, detener e iniciar servicios automáticamente.

🔹 Reiniciar un Servicio

---
- name: Reiniciar un servicio en Windows
  hosts: windows
  gather_facts: no
  vars:
    service_name: "Spooler" # Cambia esto al nombre del servicio que quieres reiniciar

  tasks:
    - name: Reiniciar el servicio
      ansible.windows.win_service:
        name: "{{ service_name }}"
        state: restarted

🔹 Detener un Servicio

---
- name: Detener un servicio en Windows
  hosts: windows
  gather_facts: no
  vars:
    service_name: "Spooler" # Cambia esto al nombre del servicio que quieres detener

  tasks:
    - name: Detener el servicio
      ansible.windows.win_service:
        name: "{{ service_name }}"
        state: stopped

🔹 Iniciar un Servicio

---
- name: Arrancar un servicio en Windows
  hosts: windows
  gather_facts: no
  vars:
    service_name: "Spooler" # Cambia esto al nombre del servicio que quieres iniciar

  tasks:
    - name: Arrancar el servicio
      ansible.windows.win_service:
        name: "{{ service_name }}"
        state: started

🖥️ Habilitar Escritorio Remoto (RDP) en Windows

La típica: necesitas conectarte a un servidor y, sorpresa, RDP está deshabilitado. 🙄 Vamos a evitar este dolor de cabeza.

🔹 Habilitar Escritorio Remoto en Windows

---
- name: Habilitar Escritorio Remoto en Windows
  hosts: windows
  gather_facts: no

  tasks:
    - name: Habilitar Escritorio Remoto en el registro de Windows
      ansible.windows.win_regedit:
        path: "HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server"
        name: "fDenyTSConnections"
        data: 0
        type: dword
        state: present

    - name: Permitir conexiones de Escritorio Remoto en la configuración de Windows
      ansible.windows.win_shell: |
        (Get-WmiObject -Class Win32_TerminalServiceSetting -Namespace root\cimv2\terminalservices).SetAllowTsConnections(1,1)
      register: resultado_habilitar_rdp
      changed_when: resultado_habilitar_rdp.rc == 0

    - name: Habilitar RDP en el Firewall de Windows
      community.windows.win_firewall_rule:
        name: "Permitir Escritorio Remoto"
        enable: yes
        direction: in
        action: allow
        protocol: TCP
        localport: 3389

    - name: Asegurar que el servicio de Escritorio Remoto esté habilitado y en ejecución
      ansible.windows.win_service:
        name: "TermService"
        start_mode: auto
        state: started

Con este playbook se activa RDP, se abre el puerto en el firewall y el servicio de escritorio remoto se inicia automáticamente.

📌 Copiar y pegar archivos/carpetas

Una de las cosas más típicas y necesarias.

---
- name: coipiar archivos
  hosts: windows
  tasks:
    - name: Copiar archivo a destino
      win_copy:
        src: /home/carlos/ansible/playbooks/windows/copia/prueba.txt
        dest: C:\users\administrator\desktop\prueba-copia.txt

    - name: Copiar archivo de destion a destino
      win_copy:
        src: C:\users\administrator\desktop\prueba-copia.txt
        dest: C:\users\administrator\downloads\prueba-copia2.txt
        remote_src: true

    - name: copiar desde Windows remoto a local
      fetch:
        src: "C://users//administrator//desktop//test.txt"
        dest: "/home/carlos/ansible/playbooks/windows/copia/test.txt"
        flat: yes

📟Ejecutar comandos en la máquina remota Windows

Impresindible saber esto.

---
- name: coipiar archivos
  hosts: windows
  tasks:
    - name: Copiar archivo a destino
      win_copy:
        src: /home/carlos/ansible/playbooks/windows/copia/prueba.txt
        dest: C:\users\administrator\desktop\prueba-copia.txt

    - name: Copiar archivo de destion a destino
      win_copy:
        src: C:\users\administrator\desktop\prueba-copia.txt
        dest: C:\users\administrator\downloads\prueba-copia2.txt
        remote_src: true

    - name: copiar desde Windows remoto a local
      fetch:
        src: "C://users//administrator//desktop//test.txt"
        dest: "/home/carlos/ansible/playbooks/windows/copia/test.txt"
        flat: yes

💡 ¿Y Ahora Qué?

Si quieres llevar esto al siguiente nivel, prueba a combinar estos playbooks en roles o ejecutarlos automáticamente en múltiples servidores con Tower/AWX/Semaphore.

Y recuerda: si puedes automatizarlo, hazlo. Más Ansible, menos estrés. 🚀

¿Tienes más ideas de playbooks útiles para Windows? Déjamelo en los comentarios y sigamos compartiendo conocimiento. 💬

error: ooops!