借助 Ventoy vhdboot 实现更好的 Windows to Go

简介

void-vtoyboot 中我提到借助 Ventoy vtoyboot,使用 void-mklive 自定义镜像,并使用 vlnk 启动本地 VDI,实现类似 Windows to Go (WTG) 的效果。

当然,那篇中实现的是 Void to Go,借助 vhdboot 和 vlink,也能实现 WTG 的加强版,Windows in a single VHD (VHDX) 的效果。

解释

首先解释一下为什么不推荐 WTG:

  1. 不再维护,Win10 1903 即 弃用,现在已经推进到 删除
  2. WTG 启动后挂载 Windows 本身的储存介质(一般是 U 盘或者移动硬盘)无法访问,这点和 void-vtoyboot 中的内核限制类似,完全失去了 U 盘启动的意义……
  3. 不支持升级,是的,WTG 本身没有升级功能 1。如果要对系统进行更新,只有重装才行。用的如果是 LTSC 还行,如果是 Canary 就自求多福吧,希望 Windows 能活得比你的硬盘久
  4. 不够通用

什么叫「通用」,还是拿上面的 vtoyboot 举例:

  • 硬盘格式自由(但不多= =),我想用 VHD 就用 VHD,想用 VDI 就用 VDI,想用 RAW 就用 RAW,甚至我吃饱了没事干相互转化着玩也丝毫不影响启动
  • 整个系统都在一个文件里,备份很简单,复制、粘贴、等待、结束╮(╯_╰)╭
  • 由于使用 VHD/VDI/RAW,可以用实机启动,也可以使用 VirtualBox/QEMU 启动。如果无聊,做成完全加载到内存的 memdisk 也未尝不可
  • vlnk 支持 U 盘启动,也支持映射本地磁盘文件
  • 如果使用 iVentoy,可以实现类 PXE,或者说超越 PXE 的网络启动

当然,vhdboot 的方法也有几个缺点:

  1. 文件很大,如果不使用 delta sync 或者 SSD,备份时间会大大拉长。这点主要怪微软,Windows 7 往后硬盘占用就极大增长 2
  2. 无分区,本身是件好事,但也让直接通过系统的 Grub(而不是 Ventoy 的 Grub)启动 Windows VHD 变得困难,反正我是没搞定那个 loopback
  3. 需要 USB 等外置储存介质,不过也是小事,映射本地磁盘文件的 vlnk 也就 32KiB
  4. 部分软件会采取极端的虚拟机检测行为,如果安装 VM 扩展插件,有时会误报

对于第一个缺点,可以(在符合许可证的前提下)使用 Windows Server 镜像,不过需要注意服务器镜像通常会对驱动进行阉割,以及部分软件会检测 Windows 版本,屏蔽服务器的安装(虽然拆包绕过即可安装,或者直接提取 INF 到对应位置就完事了),要确保自身有能力排查和解决问题。

另一种通用的方式就是参考 我的 Windows 软件之道#镜像 自行定制和封装母盘,还可以顺带注入驱动、注册表和功能设置,配合无人值守,从 OOBE 阶段就遥遥领先,进系统跑一下优化脚本,随后再用脚本自动装机,再用脚本自动恢复配置就完成初始化了。

流程

流程本身很简单,vhdboot 插件介绍页面写了几个注意事项,可以看看。

  • 自己搞定母盘,#解释我的 Windows 软件之道 都给了不少思路
  • 用 VirtualBox 或 QEMU #安装,注意启用 UEFI。如果看了 void-vtoyboot,这一步容易搞混,vhdboot 并不要求使用 VHD,对于 Windows 7 以上的系统也可以用 VHDX 安装,动态分配功能也是正常的。装机后如果觉得空间不够,随时可以用 VirtualBox 扩容
  • 启动虚拟机,安装驱动。注意部分驱动(特别是显卡驱动)会检测虚拟机环境,如果没有开启对应的 passthrough,会因为未通过检测而无法安装 3
  • 配置 Ventoy vhdboot,单独下载文件放到 Ventoy USB 对应分区即可
  • 创建 vlnk,复制到 Ventoy USB 即可在 Ventoy 中启动本地 VHD 中的 Windows4
  • 关机,在 Ventoy 通过 vlnk 启动本地磁盘上的 VHD/VHDX 中的 Windows。如果遇到了上面提到驱动检测虚拟机的问题,此时系统可能看起来怪怪的,重新安装一遍驱动,然后重启,重新通过 Ventoy 进入 Windows,这时系统应该就一切正常了

安装

上面对于安装部分仅仅一笔带过,实际上(仅仅借助虚拟机软件安装)还是有一点复杂的。当然,如果本来就知道怎么安装 Windows 到 VHD/VHDX,那其实也是小菜一碟。 由于之前做的是完全离线的 VM/WTG,最近需要新的联网开发用 WTG,从笔记中捞出了完整的创建流程,顺带记录在此。

  1. 创建 Windows VM,25G5 动态分配的 VHD
  2. 虚拟机挂载 Edgeless 光盘(勾选 Live CD)和刚刚创建的 VHD(勾选 SSD),启动
  3. 用 DiskGenius 之类的软件快速分区
    • 分区表选择 GUID (GPT),自定 1 个分区,清空所有卷标
    • 注意 Win10+ GPT 分区表需要三个分区,EFI(ESP),MBR,再一个系统盘,虽然另外两个平常看不到,但要确保在 DiskGenius 中存在
    • 安装完 Windows 回头看,确保 ESP 分区存在 /EFI/Boot/bootx64.efi/EFI/Microsoft/Boot/BCD 等一堆名字
      • bcd, bcd.log, boot,stl, bootmgfw.efi, bootmgr.efi
    • 如果想折腾 Grub loopback,这里可以记录 VHD 磁盘和 ESP 分区的 GUID(不是分区类型 GUID),但我建议还是老老实实用 Ventoy 启动
  4. 关闭 VM,弹出 Edgeless,只挂载 Windows 安装镜像和 VHD,启动,正常安装即可
    • 下面的方法过于麻烦,已弃用
    • 仍旧在 Edgeless 环境,WinNTSetup 安装 Windows,注意引导驱动器要选到 ESP 分区,安装驱动器要选到系统盘,挂载安装驱动器要改成和默认 C 盘不同的(这点似乎仅适用于硬盘已经装有 Windows 的情况?)。点击开始安装,可能会提示有个错误说 VHD 不能被选中作为引导驱动器,直接点确定。右下角的 VHD 按钮不用管,那个功能可有可无,不需要借助它也可以正常安装 Windows 到 VHD
  5. 安装镜像发现问题的临时修改方案
    • Windows:可以直接在 NTLite 或系统挂载,然后重新生成镜像即可
    • Linux:有 WM 或完整桌面环境同上,对于纯 TTY,可以使用下面的命令将文件夹制作成 ISO6
# mkisofs 命令来自 cdrtools
# 通过 cdrtools -> virt-manager-tools -> virt-manager 的依赖关系安装
mkisofs -V "SERVER" -o server.iso ./20348.2582_SERVERDATACENTER_X64_EN-US

  1. 当然如果非要做还是可以实现的,无非是修改注册表或者复制系统分区的全部文件到一个新的 VHD/VHDX,并保证权限正确,设置启动项,在新 VHD/VHDX 中升级系统,然后复制回系统分区(是不是听着很耳熟,嗯,其实和 vhdboot 的原理是类似的,完全没必要舍近求远,直接用 vhdboot 吧) ↩︎

  2. 虽然之前的版本也没精简多少,Windows 95 都要 100M 往上,能够供应日常使用的话需要 200M,而 MSDOS-6.22 真的只需要三张安装软盘的 6.7M 大小 ↩︎

  3. 这里针对的主要是 GNU/Linux 宿主机,因为 Windows 宿主机在封装母盘阶段即可直接在安装光盘中注入 Windows 驱动,从而绕开驱动安装程序对虚拟机环境的检测 ↩︎

  4. Windows 10 1803 之前的版本,存放 VHD/VHDX 的分区必须是 NTFS;Windows 10 1809(注意和前面的版本号不一样,这是 Windows 10 LTSC 2019 的母盘)开始还可以存放在 exFAT,但出于兼容性考虑,还是直接 NTFS 一劳永逸吧= = ↩︎

  5. 大小看个人需求,对于离线/纯内网访问的 Windows Server 而言,4G2C+20G SSD 的配置足以应付大多数场景。承载部分更新或托管服务时才需要扩展硬盘。对于普通 Windows,一般 50G 也够用,不在乎硬盘或者想一劳永逸完全可以分配个 200G,反正 VHDX 可以动态扩展,还可以通过 Optimize-VHD -Path "blahblah.vhdx" -Mode Retrim -Confirm 命令不定期压缩,并不会占用多余空间 ↩︎

  6. 由于 ISO 文件有很多标准,不保证其他系统也能这么用,Windows 使用的是 ISO 9660,前身为 ECMA-119 ↩︎

Vinfall's Geekademy

Sine īrā et studiō