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. 💬