How to Create Windows Server 2022 Template in vSphere - using Packer
Overview
Packer uses the HashiCorp Configuration Language - HCL - designed to allow concise descriptions of the required steps to get to a build file. This page describes the features of HCL2 exhaustively
File structure i have used:
Below two files are commonly used by all the templates. which will be called using packer tool
1. common.pkrvars.hcl
1// Virtual Machine Settings
2common_vm_version = 19
3common_tools_upgrade_policy = true
4common_remove_cdrom = true
5
6// Template and Content Library Settings
7common_template_conversion = false
8common_content_library_name = "vm_library"
9common_content_library_ovf = false
10common_content_library_destroy = false
11common_content_library_skip_export = false
12
13// Removable Media Settings
14common_iso_datastore = "OS_ISO"
15
16// Boot and Provisioning Settings
17common_data_source = "http"
18common_http_ip = null
19common_http_port_min = 8000
20common_http_port_max = 8099
21common_ip_wait_timeout = "20m"
22common_ip_settle_timeout = "5s"
23common_shutdown_timeout = "15m"
2. vsphere.pkrvars.hcl
1// vSphere Credentials - replace with your configuration
2vsphere_endpoint = "vcsa.cloudbricks.local"
3vsphere_username = "Administrator@vsphere.local"
4vsphere_password = "SuperSecretPassword"
5vsphere_insecure_connection = false
6
7// vSphere Settings
8vsphere_datacenter = "Lab"
9//vsphere_cluster = "Cluster"
10vsphere_host = "esx-base.cloudbricks.local"
11vsphere_datastore = "SSD"
12vsphere_network = "cloudbricks"
13vsphere_folder = "Templates"
14
15vsphere_set_host_for_datastore_uploads = false
Below files are used for Windows Server template
1. variables.pkr.hcl
Contains all input variables to which you assign values. Any explicit values in this file will override the declared default values (these are found in the following file). The auto extension enables Packer to use this file automatically. It does not require you to reference or pass it in the command line explicitly
1// Defines the input variables.
2
3// vSphere Credentials
4
5variable "vsphere_endpoint" {
6 type = string
7 description = "The fully qualified domain name or IP address of the vCenter Server instance."
8}
9
10variable "vsphere_username" {
11 type = string
12 description = "The username to login to the vCenter Server instance."
13 sensitive = true
14}
15
16variable "vsphere_password" {
17 type = string
18 description = "The password for the login to the vCenter Server instance."
19 sensitive = true
20}
21
22variable "vsphere_insecure_connection" {
23 type = bool
24 description = "Do not validate vCenter Server TLS certificate."
25}
26
27// vSphere Settings
28
29variable "vsphere_datacenter" {
30 type = string
31 description = "The name of the target vSphere datacenter."
32 default = ""
33}
34
35variable "vsphere_cluster" {
36 type = string
37 description = "The name of the target vSphere cluster."
38 default = ""
39}
40
41variable "vsphere_host" {
42 type = string
43 description = "The name of the target ESXi host."
44 default = ""
45}
46
47variable "vsphere_datastore" {
48 type = string
49 description = "The name of the target vSphere datastore."
50}
51
52variable "vsphere_network" {
53 type = string
54 description = "The name of the target vSphere network segment."
55}
56
57variable "vsphere_folder" {
58 type = string
59 description = "The name of the target vSphere folder."
60 default = ""
61}
62
63variable "vsphere_resource_pool" {
64 type = string
65 description = "The name of the target vSphere resource pool."
66 default = ""
67}
68
69variable "vsphere_set_host_for_datastore_uploads" {
70 type = bool
71 description = "Set this to true if packer should use the host for uploading files to the datastore."
72 default = false
73}
74
75// Installer Settings
76
77variable "vm_inst_os_language" {
78 type = string
79 description = "The installation operating system lanugage."
80 default = "en-US"
81}
82
83variable "vm_inst_os_keyboard" {
84 type = string
85 description = "The installation operating system keyboard input."
86 default = "en-US"
87}
88
89variable "vm_inst_os_image_standard_core" {
90 type = string
91 description = "The installation operating system image input for Microsoft Windows Standard Core."
92}
93
94variable "vm_inst_os_image_standard_desktop" {
95 type = string
96 description = "The installation operating system image input for Microsoft Windows Standard."
97}
98
99variable "vm_inst_os_kms_key_standard" {
100 type = string
101 description = "The installation operating system KMS key input for Microsoft Windows Standard edition."
102}
103
104variable "vm_inst_os_image_datacenter_core" {
105 type = string
106 description = "The installation operating system image input for Microsoft Windows Datacenter Core."
107}
108
109variable "vm_inst_os_image_datacenter_desktop" {
110 type = string
111 description = "The installation operating system image input for Microsoft Windows Datacenter."
112}
113
114variable "vm_inst_os_kms_key_datacenter" {
115 type = string
116 description = "The installation operating system KMS key input for Microsoft Windows Datacenter edition."
117}
118
119// Virtual Machine Settings
120
121variable "vm_guest_os_language" {
122 type = string
123 description = "The guest operating system lanugage."
124 default = "en-US"
125}
126
127variable "vm_guest_os_keyboard" {
128 type = string
129 description = "The guest operating system keyboard input."
130 default = "en-US"
131}
132
133variable "vm_guest_os_timezone" {
134 type = string
135 description = "The guest operating system timezone."
136 default = "UTC"
137}
138
139variable "vm_guest_os_family" {
140 type = string
141 description = "The guest operating system family. Used for naming and VMware Tools."
142}
143
144variable "vm_guest_os_name" {
145 type = string
146 description = "The guest operating system name. Used for naming."
147}
148
149variable "vm_guest_os_version" {
150 type = string
151 description = "The guest operating system version. Used for naming."
152}
153
154variable "vm_guest_os_edition_standard" {
155 type = string
156 description = "The guest operating system edition. Used for naming."
157 default = "standard"
158}
159
160variable "vm_guest_os_edition_datacenter" {
161 type = string
162 description = "The guest operating system edition. Used for naming."
163 default = "datacenter"
164}
165
166variable "vm_guest_os_experience_core" {
167 type = string
168 description = "The guest operating system minimal experience. Used for naming."
169 default = "core"
170}
171
172variable "vm_guest_os_experience_desktop" {
173 type = string
174 description = "The guest operating system desktop experience. Used for naming."
175 default = "dexp"
176}
177
178variable "vm_guest_os_type" {
179 type = string
180 description = "The guest operating system type, also know as guestid."
181}
182
183variable "vm_firmware" {
184 type = string
185 description = "The virtual machine firmware."
186 default = "efi-secure"
187}
188
189variable "vm_cdrom_type" {
190 type = string
191 description = "The virtual machine CD-ROM type."
192 default = "sata"
193}
194
195variable "vm_cpu_count" {
196 type = number
197 description = "The number of virtual CPUs."
198}
199
200variable "vm_cpu_cores" {
201 type = number
202 description = "The number of virtual CPUs cores per socket."
203}
204
205variable "vm_cpu_hot_add" {
206 type = bool
207 description = "Enable hot add CPU."
208}
209
210variable "vm_mem_size" {
211 type = number
212 description = "The size for the virtual memory in MB."
213}
214
215variable "vm_mem_hot_add" {
216 type = bool
217 description = "Enable hot add memory."
218}
219
220variable "vm_disk_size" {
221 type = number
222 description = "The size for the virtual disk in MB."
223}
224
225variable "vm_disk_controller_type" {
226 type = list(string)
227 description = "The virtual disk controller types in sequence."
228 default = ["pvscsi"]
229}
230
231variable "vm_disk_thin_provisioned" {
232 type = bool
233 description = "Thin provision the virtual disk."
234 default = true
235}
236
237variable "vm_network_card" {
238 type = string
239 description = "The virtual network card type."
240 default = "vmxnet3"
241}
242
243variable "common_vm_version" {
244 type = number
245 description = "The vSphere virtual hardware version."
246}
247
248variable "common_tools_upgrade_policy" {
249 type = bool
250 description = "Upgrade VMware Tools on reboot."
251 default = true
252}
253
254variable "common_remove_cdrom" {
255 type = bool
256 description = "Remove the virtual CD-ROM(s)."
257 default = true
258}
259
260// Template and Content Library Settings
261
262variable "common_template_conversion" {
263 type = bool
264 description = "Convert the virtual machine to template. Must be 'false' for content library."
265 default = false
266}
267
268variable "common_content_library_name" {
269 type = string
270 description = "The name of the target vSphere content library, if used."
271 default = null
272}
273
274variable "common_content_library_ovf" {
275 type = bool
276 description = "Export to content library as an OVF template."
277 default = true
278}
279
280variable "common_content_library_destroy" {
281 type = bool
282 description = "Delete the virtual machine after exporting to the content library."
283 default = true
284}
285
286variable "common_content_library_skip_export" {
287 type = bool
288 description = "Skip exporting the virtual machine to the content library. Option allows for testing/debugging without saving the machine image."
289 default = false
290}
291
292// OVF Export Settings
293
294variable "common_ovf_export_enabled" {
295 type = bool
296 description = "Enable OVF artifact export."
297 default = false
298}
299
300variable "common_ovf_export_overwrite" {
301 type = bool
302 description = "Overwrite existing OVF artifact."
303 default = true
304}
305
306// Removable Media Settings
307
308variable "common_iso_datastore" {
309 type = string
310 description = "The name of the source vSphere datastore for the guest operating system ISO."
311}
312
313variable "iso_path" {
314 type = string
315 description = "The path on the source vSphere datastore for the guest operating system ISO."
316}
317
318variable "iso_file" {
319 type = string
320 description = "The file name of the guest operating system ISO."
321}
322
323// Boot Settings
324
325variable "common_data_source" {
326 type = string
327 description = "The provisioning data source. One of `http` or `disk`."
328}
329
330variable "common_http_ip" {
331 type = string
332 description = "Define an IP address on the host to use for the HTTP server."
333 default = null
334}
335
336variable "common_http_port_min" {
337 type = number
338 description = "The start of the HTTP port range."
339}
340
341variable "common_http_port_max" {
342 type = number
343 description = "The end of the HTTP port range."
344}
345
346variable "vm_boot_order" {
347 type = string
348 description = "The boot order for virtual machines devices."
349 default = "disk,cdrom"
350}
351
352variable "vm_boot_wait" {
353 type = string
354 description = "The time to wait before boot."
355}
356
357variable "vm_boot_command" {
358 type = list(string)
359 description = "The virtual machine boot command."
360 default = []
361}
362
363variable "vm_shutdown_command" {
364 type = string
365 description = "Command(s) for guest operating system shutdown."
366}
367
368variable "common_ip_wait_timeout" {
369 type = string
370 description = "Time to wait for guest operating system IP address response."
371}
372
373variable "common_ip_settle_timeout" {
374 type = string
375 description = "Time to wait for guest operating system IP to settle down."
376 default = "5s"
377}
378
379variable "common_shutdown_timeout" {
380 type = string
381 description = "Time to wait for guest operating system shutdown."
382}
383
384// Communicator Settings and Credentials
385
386
387
388// Communicator Credentials
389
390variable "communicator_port" {
391 type = string
392 description = "The port for the communicator protocol."
393}
394
395variable "communicator_timeout" {
396 type = string
397 description = "The timeout for the communicator protocol."
398}
399
400// Provisioner Settings
401
402variable "scripts" {
403 type = list(string)
404 description = "A list of scripts and their relative paths to transfer and run."
405 default = []
406}
407
408variable "inline" {
409 type = list(string)
410 description = "A list of commands to run."
411 default = []
412}
413
414// HCP Packer Settings
415
416variable "common_hcp_packer_registry_enabled" {
417 type = bool
418 description = "Enable the HCP Packer registry."
419 default = false
420}
2. windows-server.pkr.hcl
This file contains the blocks as mentioned in the refernece, from declared variables, build and source blocks. Packer uses this to automate the VM template creation.
1
2// BLOCK: packer
3// The Packer configuration.
4
5packer {
6 required_version = ">= 1.9.4"
7 required_plugins {
8 vsphere = {
9 source = "github.com/hashicorp/vsphere"
10 version = ">= 1.2.1"
11 }
12
13 }
14}
15
16// BLOCK: data
17// Defines the data sources.
18
19// BLOCK: locals
20// Defines the local variables.
21
22locals {
23 iso_paths = ["[${var.common_iso_datastore}] ${var.iso_path}/${var.iso_file}",
24 "[] /vmimages/tools-isoimages/${var.vm_guest_os_family}.iso"]
25 vm_name = "WIN2022"
26
27}
28
29// BLOCK: source
30// Defines the builder configuration blocks.
31
32
33source "vsphere-iso" "WIN2022_Std" {
34
35 // vCenter Server Endpoint Settings and Credentials
36 vcenter_server = var.vsphere_endpoint
37 username = var.vsphere_username
38 password = var.vsphere_password
39 insecure_connection = var.vsphere_insecure_connection
40
41 // vSphere Settings
42 datacenter = var.vsphere_datacenter
43 cluster = var.vsphere_cluster
44 host = var.vsphere_host
45 datastore = var.vsphere_datastore
46 folder = var.vsphere_folder
47 resource_pool = var.vsphere_resource_pool
48 set_host_for_datastore_uploads = var.vsphere_set_host_for_datastore_uploads
49
50 // Virtual Machine Settings
51 vm_name = local.vm_name
52 guest_os_type = var.vm_guest_os_type
53 firmware = var.vm_firmware
54 CPUs = var.vm_cpu_count
55 cpu_cores = var.vm_cpu_cores
56 CPU_hot_plug = var.vm_cpu_hot_add
57 RAM = var.vm_mem_size
58 RAM_hot_plug = var.vm_mem_hot_add
59 cdrom_type = var.vm_cdrom_type
60 disk_controller_type = var.vm_disk_controller_type
61 storage {
62 disk_size = var.vm_disk_size
63 disk_controller_index = 0
64 disk_thin_provisioned = var.vm_disk_thin_provisioned
65 }
66 network_adapters {
67 network = var.vsphere_network
68 network_card = var.vm_network_card
69 }
70 vm_version = var.common_vm_version
71 remove_cdrom = var.common_remove_cdrom
72 tools_upgrade_policy = var.common_tools_upgrade_policy
73
74
75 // Removable Media Settings
76 iso_paths = local.iso_paths
77 cd_files = [
78 "/opt/code/packer/windows/scripts/windows-init.ps1",
79 "/opt/code/packer/windows/scripts/windows-prepare.ps1",
80 "/opt/code/packer/windows/scripts/windows-vmtools.ps1",
81
82 ]
83 cd_content = {
84 "autounattend.xml" = templatefile("${abspath(path.root)}/data/autounattend.pkrtpl.hcl", {
85 build_username = "Administrator"
86 build_password = "VMware1!"
87 vm_inst_os_language = var.vm_inst_os_language
88 vm_inst_os_keyboard = var.vm_inst_os_keyboard
89 vm_inst_os_image = var.vm_inst_os_image_standard_desktop
90 vm_inst_os_kms_key = var.vm_inst_os_kms_key_standard
91 vm_guest_os_language = var.vm_guest_os_language
92 vm_guest_os_keyboard = var.vm_guest_os_keyboard
93 vm_guest_os_timezone = var.vm_guest_os_timezone
94 })
95 }
96
97 // Boot and Provisioning Settings
98 http_port_min = var.common_http_port_min
99 http_port_max = var.common_http_port_max
100 boot_order = var.vm_boot_order
101 boot_wait = var.vm_boot_wait
102 boot_command = var.vm_boot_command
103 ip_wait_timeout = var.common_ip_wait_timeout
104 ip_settle_timeout = var.common_ip_settle_timeout
105 shutdown_command = var.vm_shutdown_command
106 shutdown_timeout = var.common_shutdown_timeout
107
108 // Communicator Settings and Credentials
109 communicator = "winrm"
110 winrm_username = "Administrator"
111 winrm_password = "VMware1!"
112 winrm_port = var.communicator_port
113 winrm_timeout = var.communicator_timeout
114
115 // Template and Content Library Settings
116 convert_to_template = true
117
118}
119
120
121// BLOCK: build
122// Defines the builders to run, provisioners, and post-processors.
123
124build {
125 sources = [
126
127 "source.vsphere-iso.WIN2022_Std"
128
129 ]
130
131
132
133provisioner "powershell" {
134 scripts = formatlist("${path.cwd}/windows/scripts/%s", var.scripts)
135 }
136
137}
3. windows-server.auto.pkrvars.hcl
Once a variable is declared in the configuration, we can set it as individual or using *.auto.pkrvars.hcl
Individually, with the -var foo=bar command line option.
In variable definitions files, either specified on the command line with the -var-files values.pkrvars.hcl or automatically loaded (*.auto.pkrvars.hcl).
1
2// Installation Operating System Metadata
3vm_inst_os_language = "en-US"
4vm_inst_os_keyboard = "en-GB"
5vm_inst_os_image_standard_core = "Windows Server 2022 SERVERSTANDARDCORE"
6vm_inst_os_image_standard_desktop = "Windows Server 2022 SERVERSTANDARD"
7vm_inst_os_kms_key_standard = "VDYBN-27WPP-V4HQT-9VMD4-VMK7H"
8vm_inst_os_image_datacenter_core = "Windows Server 2022 SERVERDATACENTERCORE"
9vm_inst_os_image_datacenter_desktop = "Windows Server 2022 SERVERDATACENTER"
10vm_inst_os_kms_key_datacenter = "WX4NM-KYWYW-QJJR4-XV3QB-6VM33"
11
12// Guest Operating System Metadata
13vm_guest_os_language = "en-US"
14vm_guest_os_keyboard = "en-GB"
15vm_guest_os_timezone = "GMT Standard Time"
16vm_guest_os_family = "windows"
17vm_guest_os_name = "server"
18vm_guest_os_version = "2022"
19vm_guest_os_edition_standard = "standard"
20vm_guest_os_edition_datacenter = "datacenter"
21vm_guest_os_experience_core = "core"
22vm_guest_os_experience_desktop = "dexp"
23
24// Virtual Machine Guest Operating System Setting
25vm_guest_os_type = "windows2019srvNext_64Guest"
26
27// Virtual Machine Hardware Settings
28vm_firmware = "efi-secure"
29vm_cdrom_type = "sata"
30vm_cpu_count = 2
31vm_cpu_cores = 1
32vm_cpu_hot_add = false
33vm_mem_size = 4096
34vm_mem_hot_add = false
35vm_disk_size = 102400
36vm_disk_controller_type = ["pvscsi"]
37vm_disk_thin_provisioned = true
38vm_network_card = "vmxnet3"
39
40// Removable Media Settings
41iso_path = "ISO"
42iso_file = "WIN2022_Eval.iso"
43
44// Boot Settings
45vm_boot_order = "disk,cdrom"
46vm_boot_wait = "2s"
47vm_boot_command = ["<spacebar>"]
48vm_shutdown_command = "shutdown /s /t 10 /f /d p:4:1 /c \"Shutdown by Packer\""
49
50// Communicator Settings
51communicator_port = 5985
52communicator_timeout = "12h"
53
54// Provisioner Settings
55scripts = ["/windows-prepare.ps1"]
56inline = [
57 "Get-EventLog -LogName * | ForEach { Clear-EventLog -LogName $_.Log }"
58]
4. autounattend.pkrtpl.hcl under data folder
Windows Server 2022 Autounttend.xml content
1<?xml version="1.0" encoding="UTF-8"?>
2<unattend xmlns="urn:schemas-microsoft-com:unattend">
3 <settings pass="windowsPE">
4 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
5 <SetupUILanguage>
6 <UILanguage>${vm_inst_os_language}</UILanguage>
7 </SetupUILanguage>
8 <InputLocale>${vm_inst_os_keyboard}</InputLocale>
9 <SystemLocale>${vm_inst_os_language}</SystemLocale>
10 <UILanguage>${vm_inst_os_language}</UILanguage>
11 <UILanguageFallback>${vm_inst_os_language}</UILanguageFallback>
12 <UserLocale>${vm_inst_os_language}</UserLocale>
13 </component>
14 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
15 <DriverPaths>
16 <PathAndCredentials wcm:action="add" wcm:keyValue="1">
17 <Path>E:\Program Files\VMware\VMware Tools\Drivers\pvscsi\Win8\amd64</Path>
18 </PathAndCredentials>
19 </DriverPaths>
20 </component>
21 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
22 <DiskConfiguration>
23 <Disk wcm:action="add">
24 <DiskID>0</DiskID>
25 <WillWipeDisk>true</WillWipeDisk>
26 <CreatePartitions>
27 <!-- Windows RE Tools partition -->
28 <CreatePartition wcm:action="add">
29 <Order>1</Order>
30 <Type>Primary</Type>
31 <Size>300</Size>
32 </CreatePartition>
33 <!-- System partition (ESP) -->
34 <CreatePartition wcm:action="add">
35 <Order>2</Order>
36 <Type>EFI</Type>
37 <Size>100</Size>
38 </CreatePartition>
39 <!-- Microsoft reserved partition (MSR) -->
40 <CreatePartition wcm:action="add">
41 <Order>3</Order>
42 <Type>MSR</Type>
43 <Size>128</Size>
44 </CreatePartition>
45 <!-- Windows partition -->
46 <CreatePartition wcm:action="add">
47 <Order>4</Order>
48 <Type>Primary</Type>
49 <Extend>true</Extend>
50 </CreatePartition>
51 </CreatePartitions>
52 <ModifyPartitions>
53 <!-- Windows RE Tools partition -->
54 <ModifyPartition wcm:action="add">
55 <Order>1</Order>
56 <PartitionID>1</PartitionID>
57 <Label>WINRE</Label>
58 <Format>NTFS</Format>
59 <TypeID>DE94BBA4-06D1-4D40-A16A-BFD50179D6AC</TypeID>
60 </ModifyPartition>
61 <!-- System partition (ESP) -->
62 <ModifyPartition wcm:action="add">
63 <Order>2</Order>
64 <PartitionID>2</PartitionID>
65 <Label>System</Label>
66 <Format>FAT32</Format>
67 </ModifyPartition>
68 <!-- MSR partition does not need to be modified -->
69 <ModifyPartition wcm:action="add">
70 <Order>3</Order>
71 <PartitionID>3</PartitionID>
72 </ModifyPartition>
73 <!-- Windows partition -->
74 <ModifyPartition wcm:action="add">
75 <Order>4</Order>
76 <PartitionID>4</PartitionID>
77 <Label>OS</Label>
78 <Letter>C</Letter>
79 <Format>NTFS</Format>
80 </ModifyPartition>
81 </ModifyPartitions>
82 </Disk>
83 </DiskConfiguration>
84 <ImageInstall>
85 <OSImage>
86 <InstallFrom>
87 <MetaData wcm:action="add">
88 <Key>/IMAGE/NAME</Key>
89 <Value>${vm_inst_os_image}</Value>
90 </MetaData>
91 </InstallFrom>
92 <InstallTo>
93 <DiskID>0</DiskID>
94 <PartitionID>4</PartitionID>
95 </InstallTo>
96 </OSImage>
97 </ImageInstall>
98 <UserData>
99 <AcceptEula>true</AcceptEula>
100 <FullName>Administrator</FullName>
101 <Organization>Administrator</Organization>
102 <ProductKey>
103 <Key>${vm_inst_os_kms_key}</Key>
104 <WillShowUI>OnError</WillShowUI>
105 </ProductKey>
106 </UserData>
107 <EnableFirewall>false</EnableFirewall>
108 </component>
109 </settings>
110 <settings pass="offlineServicing">
111 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
112 <EnableLUA>false</EnableLUA>
113 </component>
114 </settings>
115 <settings pass="generalize">
116 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
117 <SkipRearm>1</SkipRearm>
118 </component>
119 </settings>
120 <settings pass="specialize">
121 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
122 <OEMInformation>
123 <HelpCustomized>false</HelpCustomized>
124 </OEMInformation>
125 <TimeZone>${vm_guest_os_timezone}</TimeZone>
126 <RegisteredOwner />
127 </component>
128 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
129 <DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon>
130 </component>
131 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
132 <DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
133 </component>
134 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
135 <SkipAutoActivation>true</SkipAutoActivation>
136 </component>
137 </settings>
138 <settings pass="oobeSystem">
139 <component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
140 <AutoLogon>
141 <Password>
142 <Value>VMware1!</Value>
143 <PlainText>true</PlainText>
144 </Password>
145 <Enabled>true</Enabled>
146 <Username>Administrator</Username>
147 </AutoLogon>
148 <OOBE>
149 <HideEULAPage>true</HideEULAPage>
150 <HideLocalAccountScreen>true</HideLocalAccountScreen>
151 <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
152 <HideOnlineAccountScreens>true</HideOnlineAccountScreens>
153 <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
154 <NetworkLocation>Work</NetworkLocation>
155 <ProtectYourPC>2</ProtectYourPC>
156 </OOBE>
157 <UserAccounts>
158 <AdministratorPassword>
159 <Value>VMware1!</Value>
160 <PlainText>true</PlainText>
161 </AdministratorPassword>
162 <LocalAccounts>
163 <LocalAccount wcm:action="add">
164 <Password>
165 <Value>VMware1!</Value>
166 <PlainText>true</PlainText>
167 </Password>
168 <Group>administrators</Group>
169 <DisplayName>Administrator</DisplayName>
170 <Name>Administrator</Name>
171 <Description>Build Account</Description>
172 </LocalAccount>
173 </LocalAccounts>
174 </UserAccounts>
175 <FirstLogonCommands>
176 <SynchronousCommand wcm:action="add">
177 <CommandLine>%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
178 <Description>Set Execution Policy 64-Bit</Description>
179 <Order>1</Order>
180 <RequiresUserInput>true</RequiresUserInput>
181 </SynchronousCommand>
182 <SynchronousCommand wcm:action="add">
183 <CommandLine>%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
184 <Description>Set Execution Policy 32-Bit</Description>
185 <Order>2</Order>
186 <RequiresUserInput>true</RequiresUserInput>
187 </SynchronousCommand>
188 <SynchronousCommand wcm:action="add">
189 <CommandLine>%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -File F:\windows-vmtools.ps1</CommandLine>
190 <Order>3</Order>
191 <Description>Install VMware Tools</Description>
192 </SynchronousCommand>
193 <SynchronousCommand wcm:action="add">
194 <CommandLine>%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -File F:\windows-init.ps1</CommandLine>
195 <Order>4</Order>
196 <Description>Initial Configuration</Description>
197 </SynchronousCommand>
198 </FirstLogonCommands>
199 </component>
200 </settings>
201</unattend>
below 3 files will be mounted as F: drive in Windows Server 2022 during installtion. and the path is mentioned in autounaatend.pkrtpl.hcl file
5. windows-init.ps1 under scripts folder
1
2<#
3 .DESCRIPTION
4 Enables Windows Remote Management on Windows builds.
5#>
6
7$ErrorActionPreference = 'Stop'
8
9# Set network connections provile to Private mode.
10Write-Output 'Setting the network connection profiles to Private...'
11$connectionProfile = Get-NetConnectionProfile
12While ($connectionProfile.Name -eq 'Identifying...') {
13 Start-Sleep -Seconds 10
14 $connectionProfile = Get-NetConnectionProfile
15}
16Set-NetConnectionProfile -Name $connectionProfile.Name -NetworkCategory Private
17
18# Set the Windows Remote Management configuration.
19Write-Output 'Setting the Windows Remote Management configuration...'
20winrm quickconfig -quiet
21winrm set winrm/config/service '@{AllowUnencrypted="true"}'
22winrm set winrm/config/service/auth '@{Basic="true"}'
23
24# Allow Windows Remote Management in the Windows Firewall.
25Write-Output 'Allowing Windows Remote Management in the Windows Firewall...'
26netsh advfirewall firewall set rule group="Windows Remote Administration" new enable=yes
27netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=allow
28
29# Reset the autologon count.
30# Reference: https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-autologon-logoncount#logoncount-known-issue
31Set-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Name AutoLogonCount -Value 0
6. windows-prepare.ps1 under scripts folder
1
2<#
3 .DESCRIPTION
4 Prepares a Windows guest operating system.
5#>
6
7$ErrorActionPreference = "Stop"
8
9
10
11# Set the Windows Explorer options.
12Write-Output "Setting the Windows Explorer options..."
13Set-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "Hidden" -Value 1 | Out-Null
14Set-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "HideFileExt" -Value 0 | Out-Null
15Set-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "HideDrivesWithNoMedia" -Value 0 | Out-Null
16Set-ItemProperty "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name "ShowSyncProviderNotifications" -Value 0 | Out-Null
17
18# Disable system hibernation.
19Write-Output "Disabling system hibernation..."
20Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Power\" -Name "HiberFileSizePercent" -Value 0 | Out-Null
21Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Power\" -Name "HibernateEnabled" -Value 0 | Out-Null
22
23# Disable TLS 1.0.s
24Write-Output "Disabling TLS 1.0..."
25New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols" -Name "TLS 1.0" | Out-Null
26New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0" -Name "Server" | Out-Null
27New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0" -Name "Client" | Out-Null
28New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" -Name "Enabled" -Value 0 | Out-Null
29New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client" -Name "DisabledByDefault" -Value 1 | Out-Null
30New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Name "Enabled" -Value 0 | Out-Null
31New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server" -Name "DisabledByDefault" -Value 1 | Out-Null
32
33# Disable TLS 1.1.
34Write-Output "Disabling TLS 1.1..."
35New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols" -Name "TLS 1.1" | Out-Null
36New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1" -Name "Server" | Out-Null
37New-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1" -Name "Client" | Out-Null
38New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" -Name "Enabled" -Value 0 | Out-Null
39New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" -Name "DisabledByDefault" -Value 1 | Out-Null
40New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" -Name "Enabled" -Value 0 | Out-Null
41New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" -Name "DisabledByDefault" -Value 1 | Out-Null
42
43
44
45# Enable Remote Desktop.
46Write-Output "Enabling Remote Desktop..."
47Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 0 | Out-Null
48Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "UserAuthentication" -Value 0
49Enable-NetFirewallRule -Group '@FirewallAPI.dll,-28752'
50
51
52# Disable Windows Firewall.
53Write-Output "Disabling Windows Firewall..."
54Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
7. windows-vmtools.ps1 under scripts folder
1<#
2 .DESCRIPTION
3 Installs VMware Tools and runs re-attempts if the services fail on the first attempt.
4
5 .SYNOPSIS
6 - Packer requires that the VMware Tools service is running.
7 - If the "VMware Tools Service" fails to start, the script initiates a reinstallation.
8
9 .NOTES
10 The below code is mostly based on the script within the following blog post by Owen Reynolds from scriptech.io.
11 https://scriptech.io/automatically-reinstalling-vmware-tools-on-server2016-after-the-first-attempt-fails-to-install-the-vmtools-service/
12#>
13
14$ErrorActionPreference = "Stop"
15
16# Install VMWare Tools
17
18Function Get-VMToolsInstalled {
19 if (((Get-ChildItem "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall") | Where-Object { $_.GetValue( "DisplayName" ) -like "*VMware Tools*" } ).Length -gt 0) {
20 [int]$Version = "32"
21 }
22 if (((Get-ChildItem "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall") | Where-Object { $_.GetValue( "DisplayName" ) -like "*VMware Tools*" } ).Length -gt 0) {
23 [int]$Version = "64"
24 }
25 return $Version
26}
27
28# Set the current working directory to the CD-ROM that corresponds to the VMWare Tools .iso.
29
30Set-Location E:
31
32# Installation Attempt
33
34Write-Output "Installing VMware Tools..."
35Start-Process "setup64.exe" -ArgumentList '/s /v "/qb REBOOT=R"' -Wait
36
37# Check to see if the 'VMTools' service is in a 'Running' state.
38
39$Running = $false
40$iRepeat = 0
41
42while (-not $Running -and $iRepeat -lt 5) {
43
44 Start-Sleep -s 2
45 Write-Output 'Checking VMware Tools service status...'
46 $Service = Get-Service "VMTools" -ErrorAction SilentlyContinue
47 $Servicestatus = $Service.Status
48
49 if ($ServiceStatus -ne "Running") {
50 $iRepeat++
51 }
52 else {
53 $Running = $true
54 Write-Output "VMware Tools service is in a running state."
55 }
56}
57
58# If the service never enters the 'Running' state, reinstall VMware Tools.
59
60if (-not $Running) {
61 #Uninstall VMWare Tools
62 Write-Output "Uninstalling VMware Tools..."
63 if (Get-VMToolsInstalled -eq "32") {
64 $GUID = (Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -Like '*VMWARE Tools*' }).PSChildName
65 }
66 else {
67 $GUID = (Get-ItemProperty HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -Like '*VMWARE Tools*' }).PSChildName
68 }
69
70 # Uninstall VMware Tools based on 32-bit/64-bit install GUIDs captured via Get-VMToolsIsInstalled
71
72 Start-Process -FilePath msiexec.exe -ArgumentList "/X $GUID /quiet /norestart" -Wait
73
74 # Installation Attempt
75
76 Write-Output "Reintalling VMware Tools..."
77 Start-Process "setup64.exe" -ArgumentList '/s /v "/qb REBOOT=R"' -Wait
78
79 # Check to see if the 'VMTools' service is in a 'Running' state.
80
81Write-Output "Checking VMware Tools service status..."
82
83$iRepeat = 0
84while (-not $Running -and $iRepeat -lt 5) {
85 Start-Sleep -s 2
86 $Service = Get-Service "VMTools" -ErrorAction SilentlyContinue
87 $ServiceStatus = $Service.Status
88
89 if ($ServiceStatus -ne "Running") {
90 $iRepeat++
91 }
92 else {
93 $Running = $true
94 Write-Output "VMware Tools service is in a running state."
95 }
96 }
97
98 # If after the reinstall, the service is still not running, the installation is unsuccessful.
99
100 if (-not $Running) {
101 Write-Error "VMware Tools installation was unsuccessful."
102 Pause
103 }
104
105}
Now that we have all the required configurations in place, will process with build.
To start the build, enter the following command from /opt/code/packer folder
1packer build -var-file=common.pkrvars.hcl -var-file=vsphere.pkrvars.hcl windows/2022
it took, approximately 12 minutes for me to complete the template creation