开篇:为什么 2026 年还要专门写 Windows 的 Ansible?
说实话,我一度觉得 Ansible 管 Windows 是个伪命题。Linux 那边 SSH 一把梭,到了 Windows 这边,WinRM、PowerShell Remoting、Kerberos 认证——光听名字就劝退了一半人。
但现实是,我所在的团队去年接手了一个客户,他们的核心业务跑在 Windows Server 2022 上,还有一堆 2016 的老家伙在撑着。老板说“我们要上自动化”,底下的人第一反应是写 PowerShell 脚本。问题是,脚本散落在各个服务器上,版本混乱,谁改了都不知道。
这时候 Ansible 的价值就出来了。不是因为它比 PowerShell 强,而是它给你一个“声明式”的框架——你告诉它“最终状态是什么”,它自己想办法搞定。
Reddit 上 r/homelab 有个老哥说得挺实在:“What started off as a mini PC running Home Assistant and Pi-hole has somehow escalated into a full-blown VLAN-separated network and self-hosting project. I currently use this setup for messing about with Windows Servers — Domain Controllers, SQL Servers, and cyber security type stuff.” 这不就是我们的日常吗?从一个小项目滚雪球滚成庞然大物,手动维护根本扛不住。
WinRM 配置:踩坑最多的环节
先别急着写 playbook,把通信链路搞通再说。WinRM 是微软的远程管理协议,Ansible 通过它跟 Windows 说话。但默认配置下,WinRM 基本是“锁死”的状态——这安全,但也烦人。
快速启用 WinRM(适合测试环境)
在 Windows Server 上跑一行 PowerShell(以管理员身份):
Enable-PSRemoting -Force
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "*" -Force
Restart-Service WinRM
注意:TrustedHosts 设成 * 在生产环境是作死行为。后面我们会讲如何用 Kerberos 或 HTTPS 加固。
从控制节点测试连通性
ansible windows -m win_ping -i inventory.ini
如果返回 pong,恭喜你,通信通了。如果返回 unreachable,99% 是 WinRM 配置的问题。
常见翻车现场
- WinRM 服务没启动:检查
Get-Service WinRM。 - 防火墙挡了 5985/5986 端口:
New-NetFirewallRule -DisplayName "WinRM HTTP" -Direction Inbound -Protocol TCP -LocalPort 5985 -Action Allow。 - 认证方式没开:
Set-Item WSMan:\localhost\Service\Auth\Basic -Value $true(仅用于测试)。
生产级 WinRM 配置:别再裸奔了
上面那个配置只是让你跑起来,真要上生产,必须上 HTTPS + Kerberos 认证。
配置 HTTPS WinRM
$cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -DnsName "win-srv-01.example.com" -FriendlyName "WinRM HTTPS"
New-Item -Path WSMan:\localhost\Listener -Transport HTTPS -Address * -CertificateThumbprint $cert.Thumbprint -Force
Restart-Service WinRM
然后在 Ansible 的 inventory 里指定:
[windows]
win-srv-01.example.com ansible_user=admin@EXAMPLE.COM ansible_password=your_pass ansible_connection=winrm ansible_winrm_server_cert_validation=ignore ansible_winrm_transport=kerberos ansible_port=5986
关键点:ansible_winrm_server_cert_validation=ignore 是自签名证书的无奈之举。如果你有企业 CA,签个正式证书,把 ignore 改成 validate。
为什么推荐 Kerberos 而不是 Basic?
Basic 认证是明文的(即使走 HTTPS,也容易被中间人攻击)。Kerberos 是域环境下的标准方案,自动处理票据刷新,安全性高一个量级。
第一个 Playbook:给 Windows Server 装 IIS
理论说够了,上代码。下面这个 playbook 在 Windows Server 上安装 IIS,启动服务,然后部署一个简单的静态页面。
---
- name: Setup IIS on Windows Server 2026
hosts: windows
gather_facts: yes
tasks:
- name: Install IIS Web-Server role
ansible.windows.win_feature:
name: Web-Server
state: present
include_management_tools: yes
- name: Ensure IIS service is running
ansible.windows.win_service:
name: W3Svc
state: started
start_mode: auto
- name: Create website directory
ansible.windows.win_file:
path: C:\inetpub\wwwroot\myapp
state: directory
- name: Deploy index.html
ansible.windows.win_copy:
src: files/index.html
dest: C:\inetpub\wwwroot\myapp\index.html
- name: Create IIS website
ansible.windows.win_iis_website:
name: MyApp
state: started
port: 80
ip: '*'
physical_path: C:\inetpub\wwwroot\myapp
跑一下:
ansible-playbook -i inventory.ini setup-iis.yml
如果一切顺利,浏览器打开 http://win-srv-01 就能看到你的页面。
模块选择:别用 Linux 的思维写 Windows Playbook
这是新人最容易犯的错误。ansible.builtin.copy 在 Linux 上好用,但到了 Windows 上,路径分隔符、权限模型完全不一样。
| 场景 | Linux 模块 | Windows 模块 |
|---|---|---|
| 安装软件 | apt / yum | ansible.windows.win_feature(角色/功能)ansible.windows.win_chocolatey(第三方包) |
| 文件操作 | ansible.builtin.copy | ansible.windows.win_copy |
| 服务管理 | ansible.builtin.systemd | ansible.windows.win_service |
| 注册表 | 无 | ansible.windows.win_regedit |
| 执行命令 | ansible.builtin.shell / command | ansible.windows.win_shell / win_command |
一个血的教训:不要用 win_shell 去跑复杂的 PowerShell 脚本,除非你实在找不到对应的模块。模块化操作才是 Ansible 的精髓——幂等性、错误处理、状态追踪,这些 win_shell 都给不了你。
高级技巧:从事实收集到滚动更新
利用 setup 模块收集 Windows 事实
ansible windows -m setup
这个命令会返回 Windows 主机的所有信息——操作系统版本、内存、磁盘、网络配置、已安装的补丁。你可以用这些事实做条件判断:
- name: Reboot only if required by pending updates
ansible.windows.win_reboot:
when: ansible_os_family == "Windows" and ansible_architecture == "64-bit"
滚动更新:不停机部署
假设你有 3 台 Windows Server 做负载均衡,更新应用时不能全停了。用 serial 关键字实现滚动:
- name: Rolling update of Windows web servers
hosts: windows_web
serial: 1
tasks:
- name: Take server out of load balancer pool
ansible.windows.win_shell: |
# 假设你用 NLB 或 HAProxy,这里调用 API 把节点摘掉
Invoke-RestMethod -Uri "http://loadbalancer/api/drain?server={{ inventory_hostname }}"
delegate_to: localhost
- name: Update application files
ansible.windows.win_copy:
src: app_v2/
dest: C:\MyApp\
- name: Restart application service
ansible.windows.win_service:
name: MyAppService
state: restarted
- name: Add server back to load balancer pool
ansible.windows.win_shell: |
Invoke-RestMethod -Uri "http://loadbalancer/api/enable?server={{ inventory_hostname }}"
delegate_to: localhost
2026 年社区都在吵什么?
翻了一下最近的 Reddit 和 X,大家对 Ansible + Windows 的态度两极分化。
支持派说:Ansible 的声明式模型比 PowerShell DSC 更直观,学习成本更低。特别是团队里既有 Linux 也有 Windows 工程师时,统一用 Ansible 减少了工具链的碎片化。
反对派说:WinRM 太脆弱了,动不动就断连,调试起来比 SSH 痛苦十倍。有个老哥在 r/devops 里吐槽:“I spent more time debugging WinRM than actually writing the playbook. It’s 2026, why is this still a thing?”
我的看法:两边都有道理。WinRM 确实不如 SSH 稳定,但如果你把 HTTPS 和 Kerberos 配好,日常使用基本没问题。真正的痛点在于——Windows 的模块生态远不如 Linux 丰富。你很难找到一个社区维护的、质量可靠的 win_nginx 或 win_docker 模块。很多时候你还是得回到 win_shell 去调 PowerShell,这又回到了“脚本散落”的老问题。
最佳实践速查表
| 实践 | 推荐方案 | 理由 |
|---|---|---|
| 认证方式 | Kerberos(域环境)或 CredSSP(非域环境) | 安全性高,支持双跳 |
| 传输协议 | HTTPS(5986) | 加密传输,防中间人 |
| 证书管理 | 企业 CA 签发的证书 | 避免 ignore 跳过验证 |
| 模块选择 | 优先使用 ansible.windows.* 模块 | 幂等性、错误处理更好 |
| 事实收集 | 开启 gather_facts: yes | 为条件判断提供数据 |
| 密码管理 | Ansible Vault 或 CyberArk/Azure Key Vault | 绝不把密码明文写在 inventory 里 |
| 测试环境 | Docker 或 Vagrant 启动 Windows 容器 | 快速验证 playbook 语法 |
| 错误处理 | 使用 ignore_errors 和 failed_when | 精细控制 playbook 执行流程 |
写在最后
Ansible + Windows Server 的组合在 2026 年依然不是一个“甜点”选项——它不像 Linux 那边那么丝滑。但如果你面对的是 Windows 生态的存量系统(AD、Exchange、SQL Server),Ansible 可能是最不坏的选择。
我的建议是:从小处着手。先用 Ansible 做补丁管理或服务重启这种低风险操作,等团队积累经验了,再逐步扩展到应用部署和配置管理。别一上来就想把整个数据中心自动化——你会被 WinRM 的报错淹没的。
最后,如果你在配置过程中卡住了,去 Reddit 的 r/ansible 或 r/homelab 搜一下。大概率有人已经踩过同样的坑了。
常见问题(FAQ)
Q: WinRM 连接频繁断开怎么办?
检查网络稳定性、防火墙规则,以及 WinRM 服务的超时设置。增加 ansible_winrm_operation_timeout_sec 和 ansible_winrm_read_timeout_sec 的值。
Q: 非域环境下能用 Ansible 管理 Windows 吗?
可以,使用 HTTPS + 自签名证书 + Basic 认证,但生产环境不推荐。可以考虑 CredSSP 或 NTLM 作为替代。
Q: Ansible 能管理 Windows 10/11 桌面版吗?
可以,Windows 10/11 专业版和企业版都支持 WinRM。但微软官方建议使用 Windows Server 作为管理节点。
Q: 如何调试 Ansible 的 Windows 模块?
在 playbook 中添加 -vvvv 参数启用详细日志。同时检查 Windows 端的 WinRM 日志:Get-WinEvent -LogName Microsoft-Windows-WinRM/Operational。
Q: PowerShell DSC 和 Ansible 哪个好?
DSC 在配置管理上更原生,但 Ansible 的优势在于跨平台统一管理和更丰富的社区生态。如果你只有 Windows 环境,DSC 值得考虑;如果是混合环境,选 Ansible。