这篇文章给出一套可复现流程:在 Proxmox VE(PVE)上把 Windows 11 做成可克隆、可在 PVE 面板注入用户名/密码/静态 IP/主机名、并且宿主机能读取 IP / 优雅关机的基础通用模板。适用对象是需要批量交付 Windows VM 的运维/平台/研发同学;你会得到一套从建 VM、安装驱动与 Guest Agent、接入 Cloud-Init(ConfigDrive + Cloudbase-Init)、到 Sysprep 泛化封模和常见故障定位的完整 SOP。
1)环境与版本(含适用边界)
1.1 环境信息(示例)
| 项目 | 值 |
|---|---|
| 虚拟化平台 | Proxmox VE(PVE) |
| Guest OS | Windows 11 25H2(示例) |
| Cloud-Init 注入 | PVE CloudInit Drive(ConfigDrive2) + Cloudbase-Init |
| 宿主管理 | QEMU Guest Agent(PVE 启用 + Windows 内安装) |
| VirtIO 驱动 | virtio-win ISO |
1.2 目标(模板交付标准)
- PVE 可读到 VM IP、可优雅关机:PVE 勾选 QEMU Agent + Windows 内 QEMU Guest Agent 正常运行
- PVE Cloud-Init 页面可注入:user / password / static IP / hostname
- 克隆后不冲突:Sysprep /generalize + 清理 Cloudbase-Init 执行状态(避免克隆后不再执行注入)
1.3 合规/安全提醒(建议读完再选)
- 绕过 TPM / Secure Boot 检查属于“非标准安装路径”,可能不符合企业基线与微软支持边界;生产模板更建议用 OVMF + vTPM 2.0 + Secure Boot(PVE 原生支持)。
- 本文会给出“绕过安装门槛”的可复现步骤,但更推荐你在交付标准中明确:生产=不绕过;实验/临时=可绕过。
2)方案概述(一句话结论 + 关键点)
**结论:**模板采用 VirtIO 驱动 + QEMU Guest Agent + PVE CloudInit Drive(ConfigDrive2)+ Cloudbase-Init + Sysprep 组合:
- PVE CloudInit Drive 负责把“用户/密码/网络/主机名”写进 ConfigDrive;
- Cloudbase-Init 在 Windows 内读取 ConfigDrive 并落地配置;
- QEMU Guest Agent 提供宿主机读取 IP / 关机等管理能力;
- Sysprep 做 Windows 正规泛化,避免克隆冲突。
关键点(高频踩坑):
- PVE Cloud-Init 注入生效要两端满足:VM 已挂 CloudInit Drive + Windows 已安装并能运行 Cloudbase-Init
- QEMU Guest Agent 生效要两端满足:PVE Options 启用 Agent + Windows 内安装 virtio-serial/guest-tools + QEMU-GA 服务 running
- Cloudbase-Init 配置文件需注意编码:在中文系统里容易遇到 GBK 解码失败;建议配置文件保持 纯 ASCII(无中文注释/特殊字符)
3)落地步骤(建机 → 安装 → 配置 → 验证)
3.1 准备材料(PVE 侧)
- Windows11 ISO安装镜像
- VirtIO ISO
https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.285-1/ - Cloudbase-Init
https://github.com/cloudbase/cloudbase-init/releases
3)落地步骤(可复现流程)
3.1 PVE 创建虚拟机
Win11 / Server 2022/2025 强烈建议按 Proxmox 的 Win11 最佳实践走:创建 VM 时选择对应 Windows Guest OS,并在 System 里启用 QEMU Agent;磁盘走 SCSI + “VirtIO SCSI single”。https://pve.proxmox.com/wiki/Windows_11_guest_best_practices?utm_source=chatgpt.com
3.2 PVE 创建 VM(建议参数)
建议用(性能/兼容性/可运维)默认组合:
- Machine:q35
- BIOS:OVMF (UEFI);添加 EFI Disk
- Disk:SCSI + Controller 选 VirtIO SCSI single
- NIC:VirtIO
- System:勾选 QEMU Agent = Enabled
- 安装介质:挂 Windows ISO;同时挂 virtio-win.iso(或勾选“添加额外驱动器”)
客户机操作系统类别为:Microsoft Windows。选择版本11/2022/2025,勾选为VirtIO驱动程序添加额外驱动器,选择刚才下载的virtio-win.iso

BIOS选择OVMF,勾选Qemu代理,勾选添加EFI磁盘,我这里不建议勾选TPM。

3.3 安装 Windows(含绕过 TPM / SecureBoot / 无网络 OOBE)
3.3.1(可选)绕过 TPM / SecureBoot 检查
安装界面按 Shift + F10 打开 CMD,执行:
REG ADD HKLM\SYSTEM\Setup\LabConfig /v BypassTPMCheck /t REG_DWORD /d 1
REG ADD HKLM\SYSTEM\Setup\LabConfig /v BypassSecureBootCheck /t REG_DWORD /d 1或用 regedit 在 HKEY_LOCAL_MACHINE\SYSTEM\Setup 下创建 LabConfig,并创建两个 DWORD:
BypassSecureBootCheck = 1
BypassTPMCheck = 1
3.3.2 加载 VirtIO 存储驱动(否则看不到磁盘)
在选择磁盘页面点“加载驱动程序”,选 virtio ISO 中类似目录:
vioscsi\win11\amd64

3.3.3(可选)绕过“必须联网”OOBE
若 OOBE 阶段提示无网络、无法继续,可在 Shift + F10 打开 CMD 后执行:
oobe\BypassNRO.cmd
重启后选择“我没有 Internet 连接”继续。

3.4 安装 VirtIO Guest Tools + 启动 QEMU Guest Agent
进入桌面后,从 virtio-win 光驱执行:
virtio-win-gt-x64.msivirtio-win-guest-tools.exe
安装完成后,拉起 QEMU Guest Agent(服务名可能不同,先查再启):

装完后用 PowerShell 把 QEMU GA 服务拉起并设为自启动(不同包服务名略有差异;下列是常见写法):
Start-Service -Name 'QEMU-GA'
Set-Service -Name 'QEMU-GA' -StartupType Automatic验证点:
- PVE → VM Summary 能显示 IP(或 Agent 信息开始出现)
- Windows:
Get-Service QEMU-GA
建议此时开启RDP远程桌面服务方便后续配置。
3.5 安装CloudInit
3.5.1 PVE WebUI
- 关机 VM
- VM → Hardware → Add → CloudInit Drive
- Storage 选系统盘存储(如
local-lvm) - VM → Cloud-Init:填写
ciuser / cipassword / ipconfig0 / DNS→ Regenerate Image → 开机

3.6 安装 Cloudbase-Init(Windows 侧)并配置 ConfigDrive
安装 Cloudbase-Init 时勾选:
- Run Cloudbase-Init service as LocalSystem

安装完成后不要点这个勾选框。

安装完成后修改配置文件:C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\cloudbase-init.conf
首先修改cloudbase-init.conf文件编辑权限,右键文件——属性,赋予Users完整权限。

3.6.1 推荐配置(PVE ConfigDrive2 + 静态 IP)
配置文件建议保持 纯 ASCII(避免中文系统默认 GBK 解码报错)。
[DEFAULT]
; --- Account ---
username=Admin
groups=Administrators
rename_admin_user=true
; --- Password injection ---
inject_user_password=true
first_logon_behaviour=no
; --- Datasource: PVE uses ConfigDrive (configdrive2 for Windows) ---
metadata_services=cloudbaseinit.metadata.services.configdrive.ConfigDriveService
; --- Logging ---
verbose=true
debug=true
log_dir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
log_file=cloudbase-init.log
default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
logging_serial_port_settings=
; --- Network helpers ---
mtu_use_dhcp_config=false
ntp_use_dhcp_config=false
; --- Local scripts (optional) ---
local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
; --- Hostname ---
netbios_host_name_compatibility=false
; --- Execution ---
allow_reboot=true
stop_service_on_exit=true
check_latest_version=false
; --- Plugins order matters ---
plugins=cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin,cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,cloudbaseinit.plugins.windows.createuser.CreateUserPlugin,cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin,cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin,cloudbaseinit.plugins.common.userdata.UserDataPlugin,cloudbaseinit.plugins.common.localscripts.LocalScriptsPlugin
; --- Tools path (keep yours) ---
bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
[config_drive]
types=iso
locations=cdrom
记得给Admin账户启用

重启后就可以在PVE的Cloud-init配置中修改IP了

3.6.2 快速验证(注入是否执行)
# 1) 服务状态(按你的配置 stop_service_on_exit=true,执行完会自动停)
Get-Service cloudbase-init
# 2) 看日志(关键:Config Drive found / Metadata service loaded / NetworkConfigPlugin)
Get-Content "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\cloudbase-init.log" -Tail 200
# 3) 验证 IP
Get-NetIPAddress -AddressFamily IPv4 | Format-Table -Aut4)可选实践(按需启用:OpenSSH / 精简 App / 更新策略)
4.1 安装OpenSSH-Server
https://github.com/PowerShell/Win32-OpenSSH/releases
下载并解压到C:\Program Files\
先放行PowerShell 执行策略
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force启动与开机自启 + 防火墙
.\install-sshd.ps1
# 设置开机自动启动
Start-Service sshd
Set-Service sshd -StartupType Automatic
Start-Service ssh-agent
Set-Service ssh-agent -StartupType Automatic
Get-Service sshd,ssh-agent | Format-Table Name,Status,StartType
# 放行 Windows 防火墙 22 端口
if (-not (Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -Name "OpenSSH-Server-In-TCP" `
-DisplayName "OpenSSH Server (sshd)" `
-Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 22
}
Get-NetFirewallRule -Name "OpenSSH-Server-In-TCP" | Format-Table -Auto
# 本机监听检查
netstat -ano | findstr ":22"
# 看 sshd 配置语法(可选)
& "C:\Program Files\OpenSSH-Win64\sshd.exe" -t
然后开机就可以通过SSH端口远程连接了
4.2 禁用Windows Defender
参考代码,下载执行即可:https://github.com/ionuttbara/windows-defender-remover
关闭安全防护会显著提高风险,并让后续补丁/排障成本上升。
4.3 禁用Windows自动更新
参考代码,下载执行即可:https://github.com/tsgrgo/windows-update-disabler
关闭系统更新会显著提高风险,并让后续补丁/排障成本上升。
4.4 去除垃圾应用
卸载服务器上不需要的Xbox、GameBar等插件
O&O AppBuster(推荐给“点点就完事”)
- 便携、免费,专门用来卸载 Windows 10/11 预装/隐藏应用,并且通常支持恢复。
适合:你做模板时想手工删掉一批 Xbox/广告/游戏类 App,但又不想写脚本。

Chris Titus Tech WinUtil(一个命令打开工具箱)
irm "https://christitus.com/win" | iex5)封装为模板(Sysprep + 清理注入状态 + 克隆验收)
5.1 封模前检查清单(PVE)
- Options → QEMU Guest Agent:Enabled
- Hardware → 已挂 CloudInit Drive
- Cloud-Init 页面可正常 Regenerate
5.2 封模前清理(Windows)
目的:确保克隆后 Cloudbase-Init 会再次执行注入,且 SSH host key 不复用。
# 1) 清 Cloudbase-Init 执行状态(用于“测试反复注入”或“封模确保克隆会跑”)
# 注意:这会让 Cloudbase-Init 下次启动重新跑插件
Remove-Item -Recurse "HKLM:\Software\Cloudbase Solutions" -Force -ErrorAction SilentlyContinue
# 2) 清 Cloudbase-Init 日志(可选)
Remove-Item "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\*" -Force -ErrorAction SilentlyContinue
# 3) 如果安装了 OpenSSH,清理 host keys(避免克隆复用)
Remove-Item "C:\ProgramData\ssh\ssh_host_*" -Force -ErrorAction SilentlyContinue
OpenSSH host key 的再生成策略与版本有关;如果你希望“开机必生成”,可以在 Cloudbase-Init LocalScripts 里加 ssh-keygen -A(前提 PATH 可用或写全路径)。
5.3 Sysprep(泛化关机)
运行:
C:\Windows\System32\Sysprep\Sysprep.exe- 选择 OOBE
- 勾选 Generalize(通用)
- 选择 Shutdown(关机)
关机后在 PVE:Convert to template。
5.4 克隆验收(必须做一次)
克隆一台新 VM 后检查:
- PVE:Summary 可显示 IP;Shutdown 工作正常
- Windows:
Get-NetIPAddress与 PVE 注入一致cloudbase-init.log能看到新一次执行- 若启用 OpenSSH:
sshdrunning,C:\ProgramData\ssh\ssh_host_*已重新生成(或按你的策略生成)
结尾(总结 / 边界 / 下一步)
- 总结
- 注入闭环:PVE CloudInit Drive(ConfigDrive2) + Windows Cloudbase-Init
- 宿主管理闭环:PVE 启用 Agent + Windows QEMU Guest Agent running
- 克隆不冲突:Sysprep /generalize + 清 Cloudbase-Init 状态 +(可选)清 SSH host keys
- 边界提醒
- 绕过 TPM / Secure Boot 属于非标准路径;生产模板建议用 vTPM2.0 + Secure Boot。
- 下一步
- 把“OpenSSH 安装 / host key 生成 / 业务基线工具安装”下沉到 Cloudbase-Init
LocalScripts,形成一次性首启脚本 - 制作“模板验收脚本”:IP/hostname/agent/sshd 状态一键检查
- 引入更新策略(WSUS/窗口期),避免用“禁用更新”来换稳定
- 把“OpenSSH 安装 / host key 生成 / 业务基线工具安装”下沉到 Cloudbase-Init
References(原文链接集合)
PVE Windows 11 best practices:
https://pve.proxmox.com/wiki/Windows_11_guest_best_practices
Cloudbase-Init:
https://github.com/cloudbase/cloudbase-init/releases
https://pve.proxmox.com/wiki/Cloud-Init_Support
Win32-OpenSSH:
https://github.com/PowerShell/Win32-OpenSSH/releases
.NET Framework:
https://dotnet.microsoft.com/zh-cn/download/dotnet-framework
PVE安装Windows11小记
https://willxup.top/archives/pve-install-win11
附录)
下载 .NET Framework 运行时大全
https://dotnet.microsoft.com/zh-cn/download/dotnet-framework