Ansible执行Windows Server 2016升级至2019的PowerShell故障排查
Ansible实现Windows Server 2016升级至2019的正确方案
Ansible是否适合执行Windows版本升级?
完全适合。Windows Server版本升级本质是调用系统自带的setup.exe执行无人值守安装,只要Ansible能正确获取升级源路径、以管理员权限执行命令、并配置足够的超时时间,就能实现自动化升级。本地PowerShell可运行的命令,调整后通过Ansible同样可以执行。
针对你的问题的修正方案
你遇到的0xC1900215、0xC190010A、0xC1900204错误,大多源于升级源路径获取不稳定、Ansible会话超时中断、权限不足或命令参数问题,以下是修正后的完整Playbook及关键说明:
修正后的Playbook
--- - hosts: win gather_facts: false vars: # 定义2019升级ISO路径(确保是正确的2019镜像) upgrade_iso_path: "C:\\17763.3650.221105-1748.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us.iso" drive_letter_store: "C:\\upgrade_drive.txt" # WinRM超时配置,避免升级过程中断 ansible_winrm_operation_timeout_sec: 3600 ansible_winrm_read_timeout_sec: 3600 tasks: - name: 挂载Windows Server 2019升级ISO win_shell: | # 检查ISO是否已挂载 $mounted = Get-DiskImage -ImagePath "{{ upgrade_iso_path }}" -ErrorAction SilentlyContinue | Where-Object {$_.ImagePath -eq "{{ upgrade_iso_path }}" -and $_.Attached} if ($mounted) { $drive = Get-DiskImage -ImagePath "{{ upgrade_iso_path }}" | Get-Volume $drive_letter = "$($drive.DriveLetter):" Write-Output "ISO已挂载,驱动器号:$drive_letter" } else { # 挂载ISO Mount-DiskImage -ImagePath "{{ upgrade_iso_path }}" -PassThru | Get-Volume $drive = Get-DiskImage -ImagePath "{{ upgrade_iso_path }}" | Get-Volume $drive_letter = "$($drive.DriveLetter):" Write-Output "已挂载ISO,驱动器号:$drive_letter" } # 保存驱动器号到文件 $drive_letter | Out-File -Path "{{ drive_letter_store }}" -Force register: iso_mount_result become: yes become_method: runas become_user: Administrator - name: 获取升级源路径 win_shell: | $drive_letter = Get-Content "{{ drive_letter_store }}" -Raw $setup_path = Join-Path -Path $drive_letter -ChildPath "setup.exe" Write-Output $setup_path register: setup_path_result - name: 执行无人值守升级 win_shell: | $setup_exe = "{{ setup_path_result.stdout }}" # 无人值守升级参数:自动升级、安静模式、忽略兼容性警告、禁用动态更新、指定镜像索引(根据你的ISO调整,Datacenter通常是4) $arguments = "/auto upgrade /quiet /compat ignorewarning /dynamicupdate disable /imageindex 4 /copylogs C:\upgrade_logs" # 启动升级并等待完成(注意:升级过程会重启服务器,Ansible会话会中断,这是正常现象) Start-Process -FilePath $setup_exe -ArgumentList $arguments -Wait become: yes become_method: runas become_user: Administrator async: 7200 # 异步执行,超时时间2小时 poll: 0 # 不等待,因为升级会重启服务器
关键修正点说明
稳定获取挂载驱动器号:
- 不再依赖解析
stdout_lines的不稳定方式,而是通过文件保存驱动器号,确保后续任务能准确获取setup.exe路径 - 直接指定2019升级ISO,避免原代码中不必要的双向判断逻辑
- 不再依赖解析
会话超时配置:
- 在vars中设置
ansible_winrm_operation_timeout_sec和ansible_winrm_read_timeout_sec为3600秒(1小时),避免升级过程中WinRM会话超时断开 - 使用
async:7200和poll:0实现异步执行,因为升级会触发服务器重启,Ansible无法持续保持会话
- 在vars中设置
权限强化:
- 所有关键任务添加
become: yes,以本地Administrator权限执行,避免权限不足导致的0xC1900204错误
- 所有关键任务添加
命令参数优化:
- 添加
/copylogs C:\upgrade_logs参数,将升级日志保存到本地,方便后续排查错误 - 明确指定
/imageindex(Windows Server 2019 Datacenter的索引通常是4,可通过D:\sources\install.wim用dism /get-wiminfo /wimfile:D:\sources\install.wim确认)
- 添加
错误排查补充
如果仍出现错误,可按以下步骤排查:
- 检查升级ISO完整性:重新下载或校验ISO的MD5/SHA256值,避免镜像损坏导致的0xC1900215错误
- 检查系统文件:在目标服务器执行
sfc /scannow和DISM /Online /Cleanup-Image /RestoreHealth修复系统文件 - 查看升级日志:通过
C:\upgrade_logs或C:\Windows\Logs\CBS\CBS.log分析具体错误原因
内容的提问来源于stack exchange,提问作者Viv
相关产品推荐
相关产品推荐

