我们计划自动为构建基础架构创建VM,以便我们能够:
- 根据需求扩展构建资源,例如,在需要时添加更多构建代理,在不需要时将其删除
- 如果/当机器死机时,重新创建全部或部分构建环境
- 当我们需要测试设置时,复制构建环境
此过程中的步骤之一是自动创建VM基本映像(在我们的示例中使用Hyper-V)。为此,我们有一个脚本:
- 使用Convert-WindowsImage脚本从ISO创建新的VHDX 。我们目前正在使用Windows 2012R2,但将在2016年推出时尽快开始使用。
- 使用我们需要的所有基本配置将无人参与脚本添加到新的VHDX
- 使用Apply-WindowsUpdate脚本用最新的Windows补丁更新VHDX
- 基于VHDX创建新的Hyper-V VM并启动它
- 等待虚拟机启动,等待WinRM服务准备好接受远程连接
- 等待Windows完成初始配置和新补丁的配置
- 应用其他补丁
- 重新启动以完成最新补丁程序的配置
- 等待Windows完成补丁配置
- 将sysprep脚本推送到计算机并调用该脚本。这将运行sysprep,然后关闭计算机
- 删除VM但保留VHDX
- 从VHDX删除sysprep和无人参与文件,然后压缩VHDX
- 将VHDX移动到模板位置并标记为只读
我们遇到的问题在步骤6和9中。理想情况下,在重新启动/关闭计算机之前,我们等待所有配置完成,但是似乎无法检测到Windows已完成配置阶段。
通过UI时,很清楚什么时候完成了任何一个步骤,因为只有在过程准备好之后,登录UI才会显示。但是,当使用WinRM远程连接到计算机时,这不太清楚,因为WinRM可以在完成配置工作之前提供对计算机的访问权限。
因此,问题是,通过Windows已经完成配置更新等的远程连接检测的最简单方法是什么,以便我们可以重新启动/关闭计算机而不会在以后引起问题。
------编辑-----
最后,我们使用的是Katherine答案的修改版本,因为我们的脚本还会等待windeploy
并ngen
完成。鉴于要ngen
等到操作系统完成初始化工作后,才能完成工作,而且作为奖励,最终的VHDX将具有ngen-ed的所有.NET框架,这意味着我们在创建新的.NET框架时无需进行处理。模板磁盘的虚拟机。如果有人感兴趣,我们用于创建VHDX模板的脚本和用于创建本地测试环境的脚本都位于github上。