概述
通过第一部分我们已经实现了CentOS7.x的模版制作,并且您可以根据不同的Linux发行版本的ks.cfg文件对其他系统(Ubuntu、CentOS8、RHEL)进行模版封装。
现在我们开始针对Windows操作系统模版进行构建,Windows和Linux使用的无人值守配置文件不同,我将通过示例帮助大家实现Windows的定制化。
同时需要注意一点,Windows操作系统镜像尽量选择包含最新补丁的版本,或自己部署本地的WSUS服务器,这样可以提高模版生成的速度。
本示例对Windows模版进行了如下的特性定制:
- 使用VMware准虚拟SCSI控制器(SCSI);
- 禁用Windows网络发现功能;
- 启动WinRM(Windows远程管理);
- 安装VMware Tools;
- 打开远程桌面(RDP);
- 配置中国标准时间(+08:00)和语言相关;
提示,由于Packer示例中,模版名是以日期作为后缀的,所以每天只会产生一个模版,同时如果做计划任务,每天都会有一个模版,要注意清理,避免过度占用磁盘空间。
相关工具:
Packer是一个开源的自动化虚拟机模版构建工具,支持私有云和公有云,几乎涵盖所有的环境。
Packer Windows Update插件是简化Windows Update的扩展插件,用于模版的Windows补丁更新。
vSphere是VMware企业级虚拟化软件,被企业客户广泛使用,具备稳定性高、性能好、安全性高和易使用的特点。
相关代码中包含Packer所需的json文件和Windows2016的自动应答文件Autounattend.xml
Windows无人参与安装中详细说明了unattend的语法
VMware虚拟机硬件版本中详细列出了vSphere对虚拟机硬件版本的支持
使用时请根据实际环境进行修改
环境需求:
- 一台Windows/Linux电脑,能够连接vCenter Server;
- Packer程序:https://packer.io/downloads.html
- Packer-Windows-Update插件:https://github.com/rgl/packer-provisioner-windows-update
- Windows Server 2016 ISO: 根据企业已购买产品情况进行下载
- VMware Tools:https://my.vmware.com/group/vmware/details?downloadGroup=VMTOOLS10310&productId=742
提示:请根据vSphere版本选择VMware Tools版本,本环境使用vSphere6.7U3,对应VMware Tools版本是10.3.10
获得Windows2016安装镜像的操作系统版本选择Index和安装key
- 在Windows中加载Windows Server 2016安装光盘;
- 运行dism /Get-imageinfo命令获取索引信息;
本示例中,Windows Server 2016安装光盘加载到驱动器F,命令如下:
dism /get-imageinfo /imagefile:F:\sources\install.wim
本示例选择安装Windows Server 2016 Datacenter (桌面体验),如下图所示Index为4,后续步骤需要修改Autounattend.xml文件中的value为4;
- 登录微软网站查询安装key; Windows产品安装的Key要和版本对应,请登录微软官方网站查询产品安装key。 https://docs.microsoft.com/zh-cn/windows-server/get-started/kmsclientkeys
Packer和Windows Update插件安装
Packer采用GO语言编写,安装非常简单,只需要将解压后的packer文件拷贝到系统bin目录下即可,下面是在Linux下的安装方式:
wget https://releases.hashicorp.com/packer/1.5.4/packer_1.5.4_linux_amd64.zip
wget https://github.com/rgl/packer-provisioner-windows-update/releases/download/v0.9.0/packer-provisioner-windows-update-linux.tgz
unzip packer_1.5.4_linux_amd64.zip
tar zxvf packer-provisioner-windows-update-linux.tgz
cp packer /usr/loca/bin
cp packer-provisioner-windows-update /usr/loca/bin
chmod +x /usr/local/bin/packer
chmod +x /usr/local/bin/packer-provisioner-windows-update
export PATH=/usr/local/bin:$PATH
packer version
VMware Tools和pvscsi驱动准备
解压缩已下载的VMware-Tools-core-10.3.10-12406962.zip;
- 上传\VMware-Tools-core-10.3.10-12406962\vmtools\windows.iso到存储中,并记录位置,后续步骤需要调用;
- 上传\VMware-Tools-core-10.3.10-12406962\floppies\pvscsi-Windows8.flp到存储中,并记录位置,后续步骤调用;
pvscsi驱动仅在使用了VMware准虚拟的SCSI控制器时候使用。
Windows Server 2016的Packer模版
我们需要两个基础文件,用于使用Packer在vSphere环境中构建CentOS 7.x模版:
- windows2016-vsphere.json文件(Packer模版);
- Autounattend.xml文件(Windows无人值守安装文件);
- scripts目录(包含置备需要的脚本);
推荐下载仓库的文件,避免拷贝粘贴可能造成的字符问题;packer-vsphere
windows2016-vsphere.json文件说明
variables段落,用于定义vCenter的相关信息和虚拟机配置,其会在Builders段落引用,注意虚拟机文件夹需要预先创建好。
- vm-name:定义虚拟机模版基础名称,在build阶段会自己增加日期后缀,以方便却别版本;
- vm-version:定义虚拟机使用什么硬件版本,当前vSphere6.7U3使用15,其他版本请查询相关工具中心的VMware虚拟机硬件版本;
- vm-folder:定义虚拟机模版保存在哪个文件夹中;
- vm-cpu-num:定义虚拟机模版配置的CPU数量,通过模版再进行部署时可以修改;
- vm-mem-size:定义虚拟机模版配置的内存容量(MB单位),通过模版再进行部署时可以修改;
- vm-disk-size:定义虚拟机磁盘容量(MB单位),默认创建1个boot分区和一个系统分区,boot分区350MB,系统分区(C盘)使用剩余空间;
- winadmin-password:定义WinRM远程登录时的口令;
- iso_url:定义系统安装光盘位置,本示例使用vSphere环境构建,所以指定共享存储的路径;
- iso_vm_tools_url:定义windows.iso光盘位置,本示例使用vSphere环境构建,所以指定共享存储的路径;
提示1:为保证ISO文件有效,可以通过参数(iso_checksum、iso_checksum_type和iso_checksum_url)验证ISO是否完成; 提示2:变量部分可以独立为var.json文件,在build时单独指定;
"variables": {
"vsphere-server": "vcenter.corp.local",
"vsphere-user": "administrator@vsphere.local",
"vsphere-password": "VMware1!",
"vsphere-datacenter": "Labs-DC02",
"vsphere-cluster": "DC02-Cluster",
"vsphere-network": "vlan100",
"vsphere-datastore": "SSD_DATASTORE,
"vm-name": "WIN2016-T",
"vm-version": "15",
"vm-folder": "Templates",
"vm-cpu-num": "2",
"vm-mem-size": "4096",
"vm-disk-size": "81920",
"winadmin-password": "VMware1!",
"iso_url": "[SSD_DATASTORE] 0-ISO/cn_windows_server_2016_vl_x64_dvd.iso",
"iso_vm_tools_url":"[SSD_DATASTORE] 0-ISO/windows.iso",
"magic_reference_date": "2006-01-02 15-04-05+0800"
},
builders段落,用于真正的构建配置,本示例中将经常需要改变的部分通过variables定义,并在此阶段引用。
- vm_name:我们采用variables中的名字和日期进行组合,isotime会获取当前日期;
- notes:显示在虚拟机的备注属性中,用于查看模版具体的构建时间;
- guest_os_type:定义虚拟机客户机操作系统,可以通VMware官方文档或者创建虚拟机后查询.vmx文件获得正确的客户机操作系统代码;
- communicator:定义远程连接虚拟机的方式,本示例使用WinRM;
- winrm_username:定义远程连接用户名;
- winrm_password:定义远程连接密码;此密码在Autounattend.xml中配置;
- ssh_username:定义provisioners阶段连接模版虚拟机的口令,此口令来自ks.cfg中的配置;
- disk_controller_type:定义虚拟机的SCSI控制器类型,这里采用更高性能的VMware准虚拟;
- disk_thin_provisioned:定义虚拟机是否使用精简磁盘;
- network_card:网卡类型,这里选择了性能最好的vmxnet3;
- convert_to_template:定义是否自动转换成模版,请根据需要选择,如果虚拟机部署编排工具不支持从模版克隆,就需要配置为false;
- iso_paths:定义加载光驱,由于Windows需要安装VMware Tools,所有挂载两个光驱,默认盘符为D和E;
- floppy_files:定义Windows无人值守安装的Autounattend.xml文件和相关脚本文件,脚本文件会在Autounattend.xml中调用,此驱动器盘符为A;
- floppy_img_path:定义pvscsi驱动文件路径,用于驱动pvscsi控制器,驱动会在Autounattend.xml中调用,此驱动器路径为B;
"builders": [
{
"type": "vsphere-iso",
"vcenter_server": "{{user `vsphere-server`}}",
"username": "{{user `vsphere-user`}}",
"password": "{{user `vsphere-password`}}",
"insecure_connection": "true",
"datacenter": "{{user `vsphere-datacenter`}}",
"cluster": "{{user `vsphere-cluster`}}",
"network": "{{user `vsphere-network`}}",
"datastore": "{{user `vsphere-datastore`}}",
"vm_name": "{{user `vm-name`}}-{{isotime \"2006-01-02\"}}",
"vm_version": "{{user `vm-version`}}",
"folder": "{{user `vm-folder`}}",
"notes": "Build via Packer in {{ (isotime | (user `magic_reference_date`)) }}",
"boot_wait": "10s",
"boot_order": "disk,cdrom,floppy",
"guest_os_type": "windows9Server64Guest",
"communicator": "winrm",
"winrm_username": "Administrator",
"winrm_password": "{{user `winadmin-password`}}",
"CPUs": "{{user `vm-cpu-num`}}",
"RAM": "{{user `vm-mem-size`}}",
"RAM_reserve_all": false,
"firmware": "bios",
"disk_controller_type": "pvscsi",
"disk_size": "{{user `vm-disk-size`}}",
"disk_thin_provisioned": true,
"network_card": "vmxnet3",
"convert_to_template": true,
"iso_paths": [
"{{user `iso_url`}}",
"{{user `iso_vm_tools_url`}}"
],
"floppy_files": [
"./autounattend.xml",
"./scripts/disable-network-discovery.cmd",
"./scripts/disable-winrm.ps1",
"./scripts/enable-rdp.cmd",
"./scripts/enable-winrm.ps1",
"./scripts/install-vm-tools.cmd",
"./scripts/set-temp.ps1"
],
"floppy_img_path": "[SSD_DATASTORE] 0-ISO/VMwareTools/pvscsi-Windows8.flp"
}
],
provissioners段落,用于系统自动化安全完成后的自定义操作,例如:更新系统补丁,清理模版等,本示例中包含ipconfig和系统更新两部分。
"provisioners": [
{
"type": "windows-shell",
"inline": [
"ipconfig"
]
},
{
"type": "windows-update",
"search_criteria": "IsInstalled=0",
"filters": [
"exclude:$_.Title -like '*Preview*'",
"include:$true"
],
"update_limit": 25
}
]
Autounattend.xml文件说明
Autounattend.xml文件的介绍很多,这里不进行详细介绍,可以参考官方文档说明,下面仅针对我定制化的内容进行说明;
- 第6-12行,定义系统语言相关配置,这里配置的中文,如果是英文请使用en-US;
- 第14-21行,定义pvscsi驱动路径,前面我们在windows2016-vsphere.json中配置的驱动器是B;
- 第23-56行,定义磁盘分区;
- 第62行,定义光盘中所选系统的Index(前面步骤已获取);
- 第76行,定义产品安装Key(前面步骤已获取);
- 第88行,定义时区为CST;
- 第131-139行,定义Windows自动登录,只登录一次,用于后续的脚本执行;
- 第205行,调用脚本安装VMware Tools;
- 第210行,调用脚本打开RDP连接;
- 第231行,定义网络位置;
- 第232行,定义UAAC;
- 第236行,定义Administrator密码;
- 第239-250行,创建ops账户用于应用人员使用;
本示例中的密码均为VMware1!,请注意自行修改。
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SetupUILanguage>
<UILanguage>zh-CN</UILanguage>
</SetupUILanguage>
<InputLocale>0804:00000804</InputLocale>
<SystemLocale>zh-CN</SystemLocale>
<UILanguage>zh-CN</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>zh-CN</UserLocale>
</component>
<component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DriverPaths>
<PathAndCredentials wcm:action="add" wcm:keyValue="A">
<!-- pvscsi-Windows8.flp -->
<Path>B:\</Path>
</PathAndCredentials>
</DriverPaths>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DiskConfiguration>
<Disk wcm:action="add">
<CreatePartitions>
<CreatePartition wcm:action="add">
<Type>Primary</Type>
<Order>1</Order>
<Size>350</Size>
</CreatePartition>
<CreatePartition wcm:action="add">
<Order>2</Order>
<Type>Primary</Type>
<Extend>true</Extend>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Active>true</Active>
<Format>NTFS</Format>
<Label>boot</Label>
<Order>1</Order>
<PartitionID>1</PartitionID>
</ModifyPartition>
<ModifyPartition wcm:action="add">
<Format>NTFS</Format>
<Label>Windows 2016</Label>
<Letter>C</Letter>
<Order>2</Order>
<PartitionID>2</PartitionID>
</ModifyPartition>
</ModifyPartitions>
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
</Disk>
</DiskConfiguration>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/INDEX</Key>
<Value>4</Value>
</MetaData><br /> </InstallFrom>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>2</PartitionID>
</InstallTo>
</OSImage>
</ImageInstall>
<UserData><br /> <!-- Product Key from https://www.microsoft.com/de-de/evalcenter/evaluate-windows-server-technical-preview?i=1 -->
<ProductKey>
<!-- Do not uncomment the Key element if you are using trial ISOs -->
<!-- You must uncomment the Key element (and optionally insert your own key) if you are using retail or volume license ISOs -->
<Key>CB7KF-BWN84-R7R2Y-793K2-8XDDG</Key>
<WillShowUI>OnError</WillShowUI>
</ProductKey>
<AcceptEula>true</AcceptEula><br /> </UserData><br /> </component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OEMInformation>
<HelpCustomized>false</HelpCustomized>
</OEMInformation>
<TimeZone>China Standard Time</TimeZone>
<RegisteredOwner/>
</component>
<component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon>
</component>
<component name="Microsoft-Windows-IE-ESC" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<IEHardenAdmin>false</IEHardenAdmin>
<IEHardenUser>false</IEHardenUser>
</component>
<component name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
</component>
<component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<SkipAutoActivation>true</SkipAutoActivation>
</component>
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RunSynchronous>
<RunSynchronousCommand wcm:action="add">
<Order>1</Order>
<Description>Set Execution Policy 64 Bit</Description>
<Path>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>2</Order>
<Description>Set Execution Policy 32 Bit</Description>
<Path>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>3</Order>
<Description>Disable WinRM</Description>
<Path>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\disable-winrm.ps1</Path>
</RunSynchronousCommand>
<RunSynchronousCommand wcm:action="add">
<Order>4</Order>
<Description>Disable Network Discovery</Description>
<Path>cmd.exe /c a:\disable-network-discovery.cmd</Path>
</RunSynchronousCommand>
</RunSynchronous>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AutoLogon>
<Password>
<Value>VMware1!</Value>
<PlainText>true</PlainText>
</Password>
<Enabled>true</Enabled>
<LogonCount>1</LogonCount>
<Username>Administrator</Username>
</AutoLogon>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
<Description>Set Execution Policy 64 Bit</Description>
<Order>1</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
<Description>Set Execution Policy 32 Bit</Description>
<Order>2</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\disable-winrm.ps1</CommandLine>
<Description>Disable WinRM</Description>
<Order>3</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v HideFileExt /t REG_DWORD /d 0 /f</CommandLine>
<Order>4</Order>
<Description>Show file extensions in Explorer</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\Console /v QuickEdit /t REG_DWORD /d 1 /f</CommandLine>
<Order>5</Order>
<Description>Enable QuickEdit mode</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v Start_ShowRun /t REG_DWORD /d 1 /f</CommandLine>
<Order>6</Order>
<Description>Show Run command in Start Menu</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\reg.exe ADD HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced\ /v StartMenuAdminTools /t REG_DWORD /d 1 /f</CommandLine>
<Order>7</Order>
<Description>Show Administrative Tools in Start Menu</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateFileSizePercent /t REG_DWORD /d 0 /f</CommandLine>
<Order>8</Order>
<Description>Zero Hibernation File</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\reg.exe ADD HKLM\SYSTEM\CurrentControlSet\Control\Power\ /v HibernateEnabled /t REG_DWORD /d 0 /f</CommandLine>
<Order>9</Order>
<Description>Disable Hibernation Mode</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE</CommandLine>
<Order>10</Order>
<Description>Disable password expiration for Administrator user</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c wmic useraccount where "name='ops'" set PasswordExpires=FALSE</CommandLine>
<Order>11</Order>
<Description>Disable password expiration for ops user</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\netsh.exe advfirewall set allprofiles state off</CommandLine>
<Order>12</Order>
<Description>Disable Windows Firewall</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c a:\install-vm-tools.cmd</CommandLine>
<Order>13</Order>
<Description>Install VMware Tools</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c a:\enable-rdp.cmd</CommandLine>
<Order>14</Order>
<Description>Enable RDP</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\set-temp.ps1</CommandLine>
<Order>15</Order>
<Description>Set Temp Folders</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\enable-winrm.ps1</CommandLine>
<Description>Enable WinRM</Description>
<Order>16</Order>
</SynchronousCommand>
</FirstLogonCommands>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Work</NetworkLocation>
<ProtectYourPC>1</ProtectYourPC>
</OOBE>
<UserAccounts>
<AdministratorPassword>
<Value>VMware1!</Value>
<PlainText>true</PlainText>
</AdministratorPassword>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value>VMware1!</Value>
<PlainText>true</PlainText>
</Password>
<Group>administrators</Group>
<DisplayName>ops</DisplayName>
<Name>ops</Name>
<Description>Ops User</Description>
</LocalAccount>
</LocalAccounts>
</UserAccounts>
<RegisteredOwner />
</component>
</settings>
<settings pass="offlineServicing">
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<EnableLUA>false</EnableLUA>
</component>
</settings>
<cpi:offlineImage cpi:source="wim:c:/wim/install.wim#Windows Server 2016 R2 SERVERSTANDARD" xmlns:cpi="urn:schemas-microsoft-com:cpi" />
</unattend>
Packer验证配置
完成配置文件的准备后,我们需要验证packer的配置文件是否正确,使用一下命令:
packer validate windows2016-vsphere.json
Packer执行构建
可以增加-timestamp-ui参数显示时间(timestamp)
packer build windows2016-vsphere.json
如果第一次构建成功,并且虚拟机名称是固定的(本示例是基于日期的)下一次构建时可以增加-force参数覆盖上一次模版;
packer build -froce windows2016-vsphere.json
检查构建结果
构建完成后,命令行如下提示;
登陆到vSpehre中可以看到模版:
完成
至此我们通过Packer实现了vSphere环境下Windows虚拟机模版的自动构建,如果希望构建其他环境可以参考官方文档。下一章我会带来通过Terraform批量部署虚拟机。
本系列一共分为四部分:
一、使用Packer自动化构建vSphere虚拟机模版——CentOS 7.x
二、使用Packer自动化构建vSphere虚拟机模版——Windows Server 2016
三、使用Terraform结合Packer批量部署虚拟机
四、使用GitLab CI/CD实现虚拟机声明式管理和自动化集成