Compare commits
	
		
			11 Commits
		
	
	
		
			08b63f30d6
			...
			Windows10
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b4f62b465d | |||
| 060ac37dc0 | |||
| b75694479a | |||
| b304a17ee1 | |||
| d155db26e7 | |||
| b2f607e2b5 | |||
| 465088b455 | |||
| 3db5e7dbf7 | |||
| f84e065e15 | |||
| 00557e50f9 | |||
| e455419986 | 
							
								
								
									
										55
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								.drone.yml
									
									
									
									
									
								
							| @@ -2,36 +2,55 @@ kind: pipeline | ||||
| type: kubernetes | ||||
| name: 'Packer Build' | ||||
|      | ||||
| volumes: | ||||
| - name: output | ||||
|   claim: | ||||
|     name: flexvolsmb-drone-output | ||||
| - name: scratch | ||||
|   claim: | ||||
|     name: flexvolsmb-drone-scratch | ||||
|  | ||||
| steps: | ||||
| - name: Debugging information | ||||
|   image: bv11-cr01.bessems.eu/library/packer-extended | ||||
|   commands: | ||||
|   - yamllint --version | ||||
|   - packer --version | ||||
|   - pwsh --version | ||||
|   - ovftool --version | ||||
| - name: Windows 10 | ||||
|   image: bv11-cr01.bessems.eu/library/packer-extended | ||||
|   pull: always | ||||
|   commands: | ||||
|   - sed -i -e "s/<<img-productkey>>/$${PRODUCTKEY}/" packer/preseed/Windows10/Autounattend.xml | ||||
|   - | | ||||
|     sed -i -e "s/<<img-password>>/$${WINRM_PASSWORD}/g" \ | ||||
|       packer/preseed/Windows10/Autounattend.xml \ | ||||
|       packer/preseed/Windows10/Sysprep_Unattend.xml | ||||
|   - | | ||||
|     yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts | ||||
|   - | | ||||
|     packer init -upgrade \ | ||||
|       ./packer | ||||
|   - | | ||||
|     packer validate \ | ||||
|       -var-file=packer/variables.vsphere.json \ | ||||
|       -var vm_name=${DRONE_COMMIT_SHA:0:10}-$DRONE_BUILD_NUMBER \ | ||||
|       -var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ | ||||
|       -var vm_guestos=win10 \ | ||||
|       -var repo_username=$${REPO_USERNAME} \ | ||||
|       -var repo_password=$${REPO_PASSWORD} \ | ||||
|       -var vsphere_password=$${VSPHERE_PASSWORD} \ | ||||
|       -var winrm_password=$${WINRM_PASSWORD} \ | ||||
|       packer/windows10.json \ | ||||
|       ./packer | ||||
|   - | | ||||
|     packer build \ | ||||
|       -on-error=cleanup \ | ||||
|       -var-file=packer/variables.vsphere.json \ | ||||
|       -var vm_name=${DRONE_COMMIT_SHA:0:10}-$DRONE_BUILD_NUMBER \ | ||||
|       -var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ | ||||
|       -var vm_guestos=win10 \ | ||||
|       -var repo_username=$${REPO_USERNAME} \ | ||||
|       -var repo_password=$${REPO_PASSWORD} \ | ||||
|       -var vsphere_password=$${VSPHERE_PASSWORD} \ | ||||
|       -var winrm_password=$${WINRM_PASSWORD} \ | ||||
|       packer/windows10.json \ | ||||
|       ./packer | ||||
|   environment: | ||||
|     VSPHERE_PASSWORD: | ||||
|       from_secret: vsphere_password | ||||
| @@ -47,8 +66,22 @@ steps: | ||||
|   volumes: | ||||
|   - name: output | ||||
|     path: /output | ||||
|  | ||||
| volumes: | ||||
| - name: output | ||||
|   claim: | ||||
|     name: flexvolsmb-drone-output | ||||
| - name: Remove temporary resources | ||||
|   image: bv11-cr01.bessems.eu/library/packer-extended | ||||
|   commands: | ||||
|   - | | ||||
|     pwsh -file scripts/Remove-Resources.ps1 \ | ||||
|       -VMName $DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ | ||||
|       -VSphereFQDN 'bv11-vc.bessems.lan' \ | ||||
|       -VSphereUsername 'administrator@vsphere.local' \ | ||||
|       -VSpherePassword $${VSPHERE_PASSWORD} | ||||
|   environment: | ||||
|     VSPHERE_PASSWORD: | ||||
|       from_secret: vsphere_password | ||||
|   volumes: | ||||
|   - name: scratch | ||||
|     path: /scratch | ||||
|   when: | ||||
|     status: | ||||
|     - success | ||||
|     - failure | ||||
|   | ||||
| @@ -1,2 +1 @@ | ||||
| # Packer.Images [](https://ci.spamasaurus.com/djpbessems/Packer.Images) | ||||
|  | ||||
| # Packer.Images [](https://ci.spamasaurus.com/djpbessems/Packer.Images) | ||||
|   | ||||
| @@ -47,7 +47,7 @@ | ||||
|                     <InstallFrom> | ||||
|                         <MetaData wcm:action="add"> | ||||
|                             <Key>/IMAGE/INDEX</Key> | ||||
|                             <Value>6</Value> | ||||
|                             <Value>3</Value> | ||||
|                         </MetaData> | ||||
|                     </InstallFrom> | ||||
|                 </OSImage> | ||||
|   | ||||
| @@ -31,21 +31,11 @@ | ||||
|             <TimeZone>UTC</TimeZone> | ||||
|             <UserAccounts> | ||||
|                 <AdministratorPassword> | ||||
|                     <Value>secret</Value> | ||||
|                     <Value><<img-password>></Value> | ||||
|                     <PlainText>true</PlainText> | ||||
|                 </AdministratorPassword> | ||||
|             </UserAccounts> | ||||
|         </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"> | ||||
|             <RunSynchronous> | ||||
|                 <RunSynchronousCommand wcm:action="add"> | ||||
|                     <Order>1</Order> | ||||
|                     <Path>c:\windows\system32\net.exe user administrator /active:yes</Path> | ||||
|                     <Description>Enable Built-in Administrator</Description> | ||||
|                     <CommandLine></CommandLine> | ||||
|                 </RunSynchronousCommand> | ||||
|             </RunSynchronous> | ||||
|         </component> --> | ||||
|     </settings> | ||||
|     <settings pass="specialize"> | ||||
|     </settings> | ||||
|   | ||||
							
								
								
									
										18
									
								
								packer/variables.pkr.hcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								packer/variables.pkr.hcl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| variable "vcenter_server" {} | ||||
| variable "vsphere_username" {} | ||||
| variable "vsphere_password" {} | ||||
|  | ||||
| variable "vsphere_host" {} | ||||
| variable "vsphere_datacenter" {} | ||||
|  | ||||
| variable "vsphere_templatefolder" {} | ||||
| variable "vsphere_folder" {} | ||||
| variable "vsphere_datastore" {} | ||||
| variable "vsphere_network" {} | ||||
|  | ||||
| variable "vm_name" {} | ||||
| variable "vm_guestos" {} | ||||
| variable "winrm_password" {} | ||||
|  | ||||
| variable "repo_username" {} | ||||
| variable "repo_password" {} | ||||
| @@ -1,11 +0,0 @@ | ||||
| { | ||||
|     "vcenter_server":           "bv11-vc01.bessems.lan", | ||||
|     "vsphere_username":         "administrator@vsphere.local", | ||||
|     "vsphere_datacenter":       "DeSchakel", | ||||
|     "vsphere_host":             "bv11-esx.bessems.eu", | ||||
|     "vsphere_hostip":           "192.168.11.200", | ||||
|     "vsphere_datastore":        "Datastore02.SSD", | ||||
|     "vsphere_folder":           "/Packer", | ||||
|     "vsphere_templatefolder":   "/Templates", | ||||
|     "vsphere_network":          "LAN" | ||||
| } | ||||
							
								
								
									
										8
									
								
								packer/vsphere.auto.pkrvars.hcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								packer/vsphere.auto.pkrvars.hcl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| vcenter_server         = "bv11-vc.bessems.lan" | ||||
| vsphere_username       = "administrator@vsphere.local" | ||||
| vsphere_datacenter     = "DeSchakel" | ||||
| vsphere_host           = "bv11-esx.bessems.lan" | ||||
| vsphere_datastore      = "Datastore01.SSD" | ||||
| vsphere_folder         = "/Packer" | ||||
| vsphere_templatefolder = "/Templates" | ||||
| vsphere_network        = "LAN" | ||||
| @@ -1,131 +0,0 @@ | ||||
| { | ||||
|     "builders": [ | ||||
|       { | ||||
|         "type":                 "vsphere-iso", | ||||
|         "name":                 "win10", | ||||
|  | ||||
|         "vcenter_server":       "{{user `vcenter_server`}}", | ||||
|         "username":             "{{user `vsphere_username`}}", | ||||
|         "password":             "{{user `vsphere_password`}}", | ||||
|         "insecure_connection":  "true", | ||||
|  | ||||
|         "vm_name":              "{{user `vm_guestos`}}-{{user `vm_name`}}", | ||||
|         "datastore":            "{{user `vsphere_datastore`}}", | ||||
|         "folder":               "{{user `vsphere_folder`}}", | ||||
|         "datacenter":           "{{user `vsphere_datacenter`}}", | ||||
|         "host":                 "{{user `vsphere_host`}}", | ||||
|         "boot_order":           "disk,cdrom", | ||||
|  | ||||
|         "guest_os_type":        "windows9_64Guest", | ||||
|  | ||||
|         "communicator":         "winrm", | ||||
|         "winrm_username":       "administrator", | ||||
|         "winrm_password":       "{{user `winrm_password`}}", | ||||
|         "winrm_timeout":        "10m", | ||||
|  | ||||
|         "cpus":                 2, | ||||
|         "RAM":                  8192, | ||||
|  | ||||
|         "network_adapters": [ | ||||
|           { | ||||
|             "network":          "{{user `vsphere_network`}}", | ||||
|             "network_card":     "vmxnet3" | ||||
|           } | ||||
|         ], | ||||
|         "storage": [ | ||||
|           { | ||||
|             "disk_size":        20480, | ||||
|             "disk_thin_provisioned": true | ||||
|           } | ||||
|         ], | ||||
|         "disk_controller_type": "lsilogic-sas", | ||||
|         "usb_controller":       "xhci", | ||||
|  | ||||
|         "iso_url":              "https://{{user `repo_username`}}:{{user `repo_password`}}@sn.itch.fyi/Repository/iso/Microsoft/Windows%2010/20H2/Win10_20H2_v2_English_x64.iso", | ||||
|         "iso_checksum":         "sha256:6C6856405DBC7674EDA21BC5F7094F5A18AF5C9BACC67ED111E8F53F02E7D13D", | ||||
|         "iso_paths": [ | ||||
|             "ISO-files/VMware-tools-windows-11.2.1-17243207/VMware-tools-windows-11.2.1-17243207.iso" | ||||
|         ], | ||||
|  | ||||
|         "floppy_files": [ | ||||
|             "packer/preseed/Windows10/Autounattend.xml", | ||||
|             "packer/preseed/Windows10/Sysprep_Unattend.xml", | ||||
|             "scripts/Set-NetworkProfile.ps1", | ||||
|             "scripts/Disable-WinRM.ps1", | ||||
|             "scripts/Enable-WinRM.ps1", | ||||
|             "scripts/Install-VMwareTools.cmd" | ||||
|         ], | ||||
|  | ||||
|         "boot_command":         "", | ||||
|         "boot_wait":            "5m", | ||||
|  | ||||
|         "shutdown_command":     "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml", | ||||
|         "shutdown_timeout":     "1h", | ||||
|  | ||||
|         "export": { | ||||
|           "images":             false | ||||
|         } | ||||
|       }      | ||||
|     ], | ||||
|     "provisioners": [ | ||||
|       { | ||||
|         "type":                 "windows-update" | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "inline": [ | ||||
|           "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12", | ||||
|           "Invoke-Expression ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "inline": [ | ||||
|           "choco config set --name=limit-output --value=LimitOutput", | ||||
|           "choco install -y 7zip.install", | ||||
|           "choco install -y putty" | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "scripts": [ | ||||
|           "scripts/Windows10/01.Disabled services.ps1", | ||||
|           "scripts/Windows10/02.Disable IPv6.ps1", | ||||
|           "scripts/Windows10/03.Power settings timeout.ps1" | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "windows-update" | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "windows-restart", | ||||
|         "restart_check_command":"powershell -command \"& {Write-Output 'Probing restart status'}\"" | ||||
|       } | ||||
|     ], | ||||
|     "post-processors": [[ | ||||
|       { | ||||
|         "type":                 "shell-local", | ||||
|         "inline": [ | ||||
|           "pwsh -file scripts/Update-OvfConfiguration.ps1 \\", | ||||
|           " -OVFFile './output-win10/{{user `vm_guestos`}}-{{user `vm_name`}}.ovf'", | ||||
|           "pwsh -file scripts/Update-Manifest.ps1 \\", | ||||
|           " -ManifestFileName './output-win10/{{user `vm_guestos`}}-{{user `vm_name`}}.mf'", | ||||
|           "ovftool --acceptAllEulas --allowExtraConfig --overwrite \\", | ||||
|           " './output-win10/{{user `vm_guestos`}}-{{user `vm_name`}}.ovf' \\", | ||||
|           " /output/Windows10.ova" | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       { | ||||
|         "type":                 "shell-local", | ||||
|         "inline": [ | ||||
|           "pwsh -file scripts/Remove-Resources.ps1 \\", | ||||
|           " -VMName '{{user `vm_guestos`}}-{{user `vm_name`}}' \\", | ||||
|           " -VSphereFQDN '{{user `vcenter_server`}}' \\", | ||||
|           " -VSphereUsername '{{user `vsphere_username`}}' \\", | ||||
|           " -VSpherePassword '{{user `vsphere_password`}}'" | ||||
|         ] | ||||
|       } | ||||
|     ]]     | ||||
|   } | ||||
							
								
								
									
										133
									
								
								packer/windows10.pkr.hcl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								packer/windows10.pkr.hcl
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| packer { | ||||
|   required_plugins { | ||||
|     windows-update = { | ||||
|       version = ">= 0.14.0" | ||||
|       source  = "github.com/rgl/windows-update" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| source "vsphere-iso" "win10" { | ||||
|   vcenter_server          = var.vcenter_server | ||||
|   username                = var.vsphere_username | ||||
|   password                = var.vsphere_password | ||||
|   insecure_connection     = "true" | ||||
|  | ||||
|   vm_name                 = "${var.vm_guestos}-${var.vm_name}" | ||||
|   datacenter              = var.vsphere_datacenter | ||||
|   host                    = var.vsphere_host | ||||
|   folder                  = var.vsphere_folder | ||||
|   datastore               = var.vsphere_datastore | ||||
|  | ||||
|   guest_os_type           = "windows9_64Guest" | ||||
|  | ||||
|   boot_order              = "disk,cdrom" | ||||
|   boot_command            = [""] | ||||
|   boot_wait               = "5m" | ||||
|  | ||||
|   communicator            = "winrm" | ||||
|   winrm_username          = "administrator" | ||||
|   winrm_password          = var.winrm_password | ||||
|   winrm_timeout           = "10m" | ||||
|  | ||||
|   CPUs                    = 2 | ||||
|   RAM                     = 8192 | ||||
|  | ||||
|   network_adapters { | ||||
|     network               = var.vsphere_network | ||||
|     network_card          = "vmxnet3" | ||||
|   } | ||||
|   storage { | ||||
|     disk_size             = 20480 | ||||
|     disk_thin_provisioned = true | ||||
|   } | ||||
|   disk_controller_type    = ["lsilogic-sas"] | ||||
|   usb_controller          = ["xhci"] | ||||
|  | ||||
|   floppy_files            = [ | ||||
|     "packer/preseed/Windows10/Autounattend.xml", | ||||
|     "packer/preseed/Windows10/Sysprep_Unattend.xml", | ||||
|     "scripts/Set-NetworkProfile.ps1", | ||||
|     "scripts/Disable-WinRM.ps1", | ||||
|     "scripts/Enable-WinRM.ps1", | ||||
|     "scripts/Install-VMwareTools.cmd" | ||||
|   ] | ||||
|   iso_checksum            = "sha256:8D1663B71280533824CF95C7AB48ADAF5A187C38FCFF5B16A569F903688916D0" | ||||
|   iso_paths               = [ | ||||
|     "ISO-files/VMware-tools-windows-11.3.5-18557794/VMware-tools-windows-11.3.5-18557794.iso" | ||||
|   ] | ||||
|   iso_url                 = "https://${var.repo_username}:${var.repo_password}@sn.itch.fyi/Repository/iso/Microsoft/Windows%2010/20H2/en_windows_10_enterprise_20H2_x64.iso" | ||||
|  | ||||
|   shutdown_command        = "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml" | ||||
|   shutdown_timeout        = "1h" | ||||
|  | ||||
|   export { | ||||
|     images                = false | ||||
|     output_directory      = "/scratch/win10" | ||||
|   } | ||||
|   remove_cdrom            = true | ||||
| } | ||||
|  | ||||
| build { | ||||
|   sources = ["source.vsphere-iso.win10"] | ||||
|  | ||||
|   provisioner "windows-update" { | ||||
|     filters = [ | ||||
|       "exclude:$_.Title -like '*Preview*'", | ||||
|       "include:$true" | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   provisioner "powershell" { | ||||
|     inline = [ | ||||
|       "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12", | ||||
|       "Invoke-Expression ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   provisioner "powershell" { | ||||
|     inline = [ | ||||
|       "choco config set --name=limit-output --value=LimitOutput", | ||||
|       "choco install -y 7zip.install", | ||||
|       "choco install -y sysinternals", | ||||
|       "choco install -y firefox" | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   provisioner "windows-update" { | ||||
|     filters = [ | ||||
|       "exclude:$_.Title -like '*Preview*'", | ||||
|       "include:$true" | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   provisioner "powershell" { | ||||
|     inline = [ | ||||
|       "New-Item -Path 'C:\\Payload\\Scripts' -ItemType 'Directory' -Force:$True -Confirm:$False" | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   provisioner "file" { | ||||
|     destination = "C:\\Payload\\" | ||||
|     source      = "scripts/Windows10/payload/" | ||||
|   } | ||||
|  | ||||
|   provisioner "powershell" { | ||||
|     scripts = [ | ||||
|       "scripts/Windows10/Register-ScheduledTask.ps1" | ||||
|     ] | ||||
|   } | ||||
|  | ||||
|   post-processor "shell-local" { | ||||
|     inline = [ | ||||
|       "pwsh -command \"& scripts/Update-OvfConfiguration.ps1 \\", | ||||
|       " -OVFFile '/scratch/win10/${var.vm_guestos}-${var.vm_name}.ovf' \\", | ||||
|       " -Parameter @{'appliance.name'='${var.vm_guestos}';'appliance.version'='${var.vm_name}'}\"", | ||||
|       "pwsh -file scripts/Update-Manifest.ps1 \\", | ||||
|       " -ManifestFileName '/scratch/win10/${var.vm_guestos}-${var.vm_name}.mf'", | ||||
|       "ovftool --acceptAllEulas --allowExtraConfig --overwrite \\", | ||||
|       " '/scratch/win10/${var.vm_guestos}-${var.vm_name}.ovf' \\", | ||||
|       " /output/Windows10.ova" | ||||
|     ] | ||||
|   } | ||||
| } | ||||
| @@ -1,156 +0,0 @@ | ||||
| { | ||||
|     "builders": [ | ||||
|       { | ||||
|         "type":                 "vsphere-iso", | ||||
|         "name":                 "win10-virtual", | ||||
|  | ||||
|         "vcenter_server":       "{{user `vcenter_server`}}", | ||||
|         "username":             "{{user `vsphere_username`}}", | ||||
|         "password":             "{{user `vsphere_password`}}", | ||||
|         "insecure_connection":  "true", | ||||
|  | ||||
|         "vm_name":              "{{user `vm_guestos`}}-{{user `vm_name`}}-virtual", | ||||
|         "datastore":            "{{user `vsphere_datastore`}}", | ||||
|         "folder":               "{{user `vsphere_folder`}}", | ||||
|         "datacenter":           "{{user `vsphere_datacenter`}}", | ||||
|         "host":                 "{{user `vsphere_host`}}", | ||||
|         "boot_order":           "disk,cdrom", | ||||
|  | ||||
|         "guest_os_type":        "windows9_64Guest", | ||||
|  | ||||
|         "communicator":         "winrm", | ||||
|         "winrm_username":       "administrator", | ||||
|         "winrm_password":       "{{user `winrm_password`}}", | ||||
|         "winrm_timeout":        "10m", | ||||
|  | ||||
|         "cpus":                 2, | ||||
|         "RAM":                  8192, | ||||
|  | ||||
|         "network_adapters": [ | ||||
|           { | ||||
|             "network":          "{{user `vsphere_network`}}", | ||||
|             "network_card":     "vmxnet3" | ||||
|           } | ||||
|         ], | ||||
|         "storage": [ | ||||
|           { | ||||
|             "disk_size":        20480, | ||||
|             "disk_thin_provisioned": true | ||||
|           } | ||||
|         ], | ||||
|         "disk_controller_type": "lsilogic-sas", | ||||
|         "usb_controller":       "xhci", | ||||
|  | ||||
|         "iso_url":              "https://sn.itch.fyi/Repository/iso/Microsoft/Windows%2010/20H2/Win10_20H2_v2_English_x64.iso", | ||||
|         "iso_checksum":         "sha256:6C6856405DBC7674EDA21BC5F7094F5A18AF5C9BACC67ED111E8F53F02E7D13D", | ||||
|         "iso_paths": [ | ||||
|             "[Datastore01.NAS] contentlib-5c2187fa-55c5-4285-b06b-3f5f1ff9428d/e9342f62-6132-4044-bd42-48cab8c77034/VMware-tools-windows-11.2.1-17243207_4f88be10-b163-446b-ad7d-992e63b0e3ac.iso" | ||||
|         ], | ||||
|  | ||||
|         "floppy_files": [ | ||||
|             "packer/preseed/Windows10/Autounattend.xml", | ||||
|             "packer/preseed/Windows10/Sysprep_Unattend.xml", | ||||
|             "scripts/Set-NetworkProfile.ps1", | ||||
|             "scripts/Disable-WinRM.ps1", | ||||
|             "scripts/Enable-WinRM.ps1", | ||||
|             "scripts/Install-VMwareTools.cmd" | ||||
|         ], | ||||
|  | ||||
|         "boot_command":         "", | ||||
|         "boot_wait":            "5m", | ||||
|  | ||||
|         "shutdown_command":     "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml", | ||||
|         "shutdown_timeout":     "1h" | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "vsphere-iso", | ||||
|         "name":                 "win10-physical", | ||||
|  | ||||
|         "vcenter_server":       "{{user `vcenter_server`}}", | ||||
|         "username":             "{{user `vsphere_username`}}", | ||||
|         "password":             "{{user `vsphere_password`}}", | ||||
|         "insecure_connection":  "true", | ||||
|  | ||||
|         "vm_name":              "{{user `vm_guestos`}}-{{user `vm_name`}}-physical", | ||||
|         "datastore":            "{{user `vsphere_datastore`}}", | ||||
|         "folder":               "{{user `vsphere_folder`}}", | ||||
|         "datacenter":           "{{user `vsphere_datacenter`}}", | ||||
|         "host":                 "{{user `vsphere_host`}}", | ||||
|         "boot_order":           "disk,cdrom", | ||||
|  | ||||
|         "guest_os_type":        "windows9_64Guest", | ||||
|  | ||||
|         "communicator":         "winrm", | ||||
|         "winrm_username":       "administrator", | ||||
|         "winrm_password":       "{{user `winrm_password`}}", | ||||
|         "winrm_timeout":        "10m", | ||||
|  | ||||
|         "cpus":                 2, | ||||
|         "RAM":                  8192, | ||||
|  | ||||
|         "network_adapters": [ | ||||
|           { | ||||
|             "network":          "{{user `vsphere_network`}}", | ||||
|             "network_card":     "vmxnet3" | ||||
|           } | ||||
|         ], | ||||
|         "storage": [ | ||||
|           { | ||||
|             "disk_size":        20480, | ||||
|             "disk_thin_provisioned": true | ||||
|           } | ||||
|         ], | ||||
|         "disk_controller_type": "lsilogic-sas", | ||||
|         "usb_controller":       "xhci", | ||||
|  | ||||
|         "iso_url":              "https://sn.itch.fyi/Repository/iso/Microsoft/Windows%2010/20H2/Win10_20H2_v2_English_x64.iso", | ||||
|         "iso_checksum":         "sha256:6C6856405DBC7674EDA21BC5F7094F5A18AF5C9BACC67ED111E8F53F02E7D13D", | ||||
|         "iso_paths": [ | ||||
|             "[Datastore01.NAS] contentlib-5c2187fa-55c5-4285-b06b-3f5f1ff9428d/e9342f62-6132-4044-bd42-48cab8c77034/VMware-tools-windows-11.2.1-17243207_4f88be10-b163-446b-ad7d-992e63b0e3ac.iso" | ||||
|         ], | ||||
|  | ||||
|         "floppy_files": [ | ||||
|             "packer/preseed/Windows10/Autounattend.xml", | ||||
|             "packer/preseed/Windows10/Sysprep_Unattend.xml", | ||||
|             "scripts/Set-NetworkProfile.ps1", | ||||
|             "scripts/Disable-WinRM.ps1", | ||||
|             "scripts/Enable-WinRM.ps1", | ||||
|             "scripts/Install-VMwareTools.cmd", | ||||
|             "scripts/Uninstall-VMwareTools.Sysprep.cmd" | ||||
|         ], | ||||
|  | ||||
|         "boot_command":         "", | ||||
|         "boot_wait":            "5m", | ||||
|  | ||||
|         "shutdown_command":     "A:\\Uninstall-VMwareTools.Sysprep.cmd", | ||||
|         "shutdown_timeout":     "1h" | ||||
|       }       | ||||
|     ], | ||||
|     "provisioners": [ | ||||
|       { | ||||
|         "type":                 "windows-update" | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "inline": [ | ||||
|           "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12", | ||||
|           "Invoke-Expression ((New-Object Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "inline": [ | ||||
|           "choco config set --name=limit-output --value=LimitOutput", | ||||
|           "choco install -y 7zip.install", | ||||
|           "choco install -y putty" | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "windows-update" | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "windows-restart", | ||||
|         "restart_check_command":"powershell -command \"& {Write-Output 'Probing restart status'}\"" | ||||
|       } | ||||
|     ] | ||||
|   } | ||||
| @@ -1,52 +0,0 @@ | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$VMName, | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$VSphereFQDN, | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$VSphereUsername, | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$VSpherePassword | ||||
| ) | ||||
|  | ||||
| $PowerCliConfigurationSplat = @{ | ||||
|     Scope                    = 'User' | ||||
|     ParticipateInCEIP        = $False | ||||
|     Confirm                  = $False | ||||
|     InvalidCertificateAction = 'Ignore' | ||||
| } | ||||
| Set-PowerCLIConfiguration @PowerCliConfigurationSplat | Out-Null | ||||
|  | ||||
| $ConnectVIServerSplat = @{ | ||||
|     Server        = $VSphereFQDN | ||||
|     User          = "$VSphereUsername" | ||||
|     Password      = "$VSpherePassword" | ||||
|     WarningAction = 'SilentlyContinue' | ||||
| } | ||||
| Connect-VIServer @ConnectVIServerSplat | Out-Null | ||||
|  | ||||
| $GetVMSplat = @{ | ||||
|     Name = $VMName | ||||
| } | ||||
| $VM = Get-VM @GetVMSplat | ||||
|  | ||||
| $GetHarddiskSplat = @{ | ||||
|     VM = $VM | ||||
| } | ||||
| $Harddisk = Get-Harddisk @GetHarddiskSplat | ||||
| $VMFolder = ($Harddisk.Filename.Substring(0, $Harddisk.Filename.LastIndexOf('/')) -split ' ')[1] | ||||
|  | ||||
| $NewDatastoreDriveSplat = @{ | ||||
|     Name      = 'ds' | ||||
|     Datastore = ($VM | Get-Datastore) | ||||
| } | ||||
| New-DatastoreDrive @NewDatastoreDriveSplat | ||||
|  | ||||
| $CopyDatastoreItemSplat = @{ | ||||
|     Item        = "ds:\$($VMFolder)\*.vmdk" | ||||
|     Destination = (Get-Item $PWD) | ||||
| } | ||||
| Copy-DatastoreItem @CopyDatastoreItemSplat | ||||
|  | ||||
| Disconnect-VIServer * -Confirm:$False | ||||
| @@ -1,51 +0,0 @@ | ||||
| #Requires -Modules 'dism' | ||||
| Param( | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$ImageName, | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$SourceFolder, | ||||
|     [Parameter(Mandatory)] | ||||
|     [string]$DestinationFile | ||||
| ) | ||||
|  | ||||
| $StartJobSplat = @{ | ||||
|     ArgumentList = $ImageName, $SourceFolder, $DestinationFile | ||||
|     ScriptBlock  = { | ||||
|         Param( | ||||
|             $ImageName, | ||||
|             $SourceFolder, | ||||
|             $DestinationFile | ||||
|         ) | ||||
|  | ||||
|         $NewWindowsImageSplat = @{ | ||||
|             Name        = $ImageName | ||||
|             CapturePath = $SourceFolder | ||||
|             ImagePath   = $DestinationFile | ||||
|             Verify      = $True | ||||
|         } | ||||
|         New-WindowsImage @NewWindowsImageSplat | ||||
|         } | ||||
| } | ||||
| $Job = Start-Job @StartJobSplat | ||||
|  | ||||
| While ($Job.State -eq 'Running') { | ||||
|     $GetItemSplat = @{ | ||||
|         Path        = $DestinationFile | ||||
|         ErrorAction = 'SilentlyContinue' | ||||
|     } | ||||
|     $OutputFile = Get-Item @GetItemSplat | ||||
|     If ($OutputFile) { | ||||
|         Write-Host "Export in progress ... $($OutputFile.FullName); Size: $('{0:n2}' -f ($OutputFile.Length / 1MB))MB" | ||||
|     } | ||||
|     Else { | ||||
|         Write-Host "Export initiating ... " | ||||
|     } | ||||
|  | ||||
|     $StartSleepSplat = @{ | ||||
|         Seconds = 30 | ||||
|     } | ||||
|     Start-Sleep @StartSleepSplat | ||||
| } | ||||
|  | ||||
| Receive-Job $Job | ||||
| Remove-Job $Job | ||||
| @@ -26,14 +26,26 @@ $ConnectVIServerSplat = @{ | ||||
| } | ||||
| Connect-VIServer @ConnectVIServerSplat | Out-Null | ||||
|  | ||||
| $RemoveVMSplat = @{ | ||||
|     VM                       = "$($VMName)*" | ||||
|     DeletePermanently        = $True | ||||
|     Confirm                  = $False | ||||
|     ErrorAction              = 'SilentlyContinue' | ||||
| $GetVMSplat = @{ | ||||
|     Name        = "*$($VMName)*" | ||||
|     ErrorAction = 'SilentlyContinue' | ||||
| } | ||||
| If ([boolean](Get-VM @GetVMSplat)) { | ||||
|     $RemoveVMSplat = @{ | ||||
|         VM                       = Get-VM @GetVMSplat | ||||
|         DeletePermanently        = $True | ||||
|         Confirm                  = $False | ||||
|         ErrorAction              = 'SilentlyContinue' | ||||
|     } | ||||
|     Remove-VM @RemoveVMSplat | ||||
| } | ||||
| Remove-VM @RemoveVMSplat | ||||
|  | ||||
| # Also delete ISO/floppy? | ||||
|  | ||||
| Disconnect-VIServer * -Confirm:$False | ||||
|  | ||||
| $RemoveItemSplat = @{ | ||||
|     Path    = "/scratch/*" | ||||
|     Recurse = $True | ||||
|     Force   = $True | ||||
|     Confirm = $False | ||||
| } | ||||
| Remove-Item @RemoveItemSplat | ||||
| @@ -1,7 +0,0 @@ | ||||
| @rem Uninstall VMware Tools | ||||
| @rem (wait for orphaned child process to finish) | ||||
| @rem Silent mode, basic UI, no reboot | ||||
| start "Uninstall VMware Tools" /b /w e:\setup64 /s /v "/qb REBOOT=R REMOVE=ALL" | ||||
|  | ||||
| @rem Initiate Sysprep | ||||
| C:\Windows\System32\Sysprep\sysprep.exe /generalize /oobe /unattend:A:\Sysprep_Unattend.xml /quiet /shutdown | ||||
| @@ -9,7 +9,8 @@ Param( | ||||
|                 Throw "'$_' is not a valid filename (within working directory '$PWD'), or access denied; aborting." | ||||
|             } | ||||
|         })] | ||||
|     [string]$OVFFile | ||||
|     [string]$OVFFile, | ||||
|     [hashtable]$Parameter | ||||
| ) | ||||
|  | ||||
| $GetContentSplat = @{ | ||||
| @@ -21,7 +22,24 @@ $ConvertFromYamlSplat = @{ | ||||
|     Yaml         = $RawContent | ||||
|     AllDocuments = $True | ||||
| } | ||||
| $OVFConfig = ConvertFrom-Yaml @ConvertFromYamlSplat | ||||
| $YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat | ||||
|  | ||||
| # Check if the respective .yml file declared substitutions which need to be parsed | ||||
| If (($YamlDocuments.Count -gt 1) -and $YamlDocuments[-1].Variables) { | ||||
|     ForEach ($Pattern in $YamlDocuments[-1].Variables) { | ||||
|         $RawContent = $RawContent -replace "\{\{ ($($Pattern.Name)) \}\}", [string](Invoke-Expression -Command $Pattern.Expression) | ||||
|     } | ||||
|     # Perform conversion to Yaml again, now with parsed file contents | ||||
|     $ConvertFromYamlSplat = @{ | ||||
|         Yaml         = $RawContent | ||||
|         AllDocuments = $True | ||||
|     } | ||||
|     $YamlDocuments = ConvertFrom-Yaml @ConvertFromYamlSplat | ||||
|     $OVFConfig = $YamlDocuments[0..($YamlDocuments.Count - 2)] | ||||
| } | ||||
| Else { | ||||
|     $OVFConfig = $YamlDocuments | ||||
| } | ||||
|  | ||||
| $SourceFile = Get-Item -Path $OVFFile | ||||
| $GetContentSplat = @{ | ||||
| @@ -62,6 +80,22 @@ If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { | ||||
| $XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) | ||||
| $XMLAttrTransport.Value = 'com.vmware.guestInfo' | ||||
| [void]$XML.SelectSingleNode('//Any:VirtualHardwareSection', $NS).Attributes.Append($XMLAttrTransport) | ||||
| ForEach ($ExtraConfig in $OVFConfig.AdvancedOptions) { | ||||
|     $XMLExtraConfig = $XML.CreateElement('vmw:ExtraConfig', $XML.DocumentElement.vmw) | ||||
|  | ||||
|     $XMLExtraConfigAttrRequired = $XML.CreateAttribute('required', $XML.DocumentElement.ovf) | ||||
|     $XMLExtraConfigAttrRequired.Value = "$([boolean]$ExtraConfig.Required)".ToLower() | ||||
|     $XMLExtraConfigAttrKey = $XML.CreateAttribute('key', $XML.DocumentElement.vmw) | ||||
|     $XMLExtraConfigAttrKey.Value = $ExtraConfig.Key | ||||
|     $XMLExtraConfigAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.vmw) | ||||
|     $XMLExtraConfigAttrValue.Value = $ExtraConfig.Value | ||||
|  | ||||
|     [void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrRequired) | ||||
|     [void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrKey) | ||||
|     [void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrValue) | ||||
|     [void]$XML.SelectSingleNode('//Any:VirtualHardwareSection', $NS).AppendChild($XMLExtraConfig) | ||||
| } | ||||
| Write-Host "Added $($OVFConfig.AdvancedOptions.Count) 'vmw:ExtraConfig' nodes" | ||||
|  | ||||
| $XMLProductSection = $XML.SelectSingleNode('//Any:ProductSection', $NS) | ||||
| If ($XMLProductSection -eq $Null) { | ||||
| @@ -94,13 +128,13 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | ||||
|         $XMLPropertyAttrKey.Value = $Property.Key | ||||
|         $XMLPropertyAttrType = $XML.CreateAttribute('type', $XML.DocumentElement.ovf) | ||||
|         Switch -regex ($Property.Type) { | ||||
|             'boolean' { | ||||
|             '^boolean' { | ||||
|                 $XMLPropertyAttrType.Value = 'boolean' | ||||
|             } | ||||
|             'int' { | ||||
|             '^int' { | ||||
|                 $XMLPropertyAttrType.Value = 'uint8' | ||||
|                 $Qualifiers = @() | ||||
|                 If ($Property.Type -match 'int\((\d*)\.\.(\d*)\)') { | ||||
|                 If ($Property.Type -match '^int\((\d*)\.\.(\d*)\)') { | ||||
|                     If ($Matches[1]) { | ||||
|                         $Qualifiers += "MinValue($($Matches[1]))" | ||||
|                     } | ||||
| @@ -112,20 +146,20 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } | ||||
|             } | ||||
|             'ip' { | ||||
|             '^ip' { | ||||
|                 $XMLPropertyAttrType.Value = 'string' | ||||
|                 $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.vmw) | ||||
|                 $XMLPropertyAttrQualifiers.Value = 'Ip' | ||||
|                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|             } | ||||
|             'password' { | ||||
|             '^password' { | ||||
|                 $XMLPropertyAttrType.Value = 'string' | ||||
|                 $XMLPropertyAttrPassword = $XML.CreateAttribute('password', $XML.DocumentElement.ovf) | ||||
|                 $XMLPropertyAttrPassword.Value = 'true' | ||||
|                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrPassword) | ||||
|  | ||||
|                 $Qualifiers = @() | ||||
|                 If ($Property.Type -match 'password\((\d*)\.\.(\d*)\)') { | ||||
|                 If ($Property.Type -match '^password\((\d*)\.\.(\d*)\)') { | ||||
|                     If ($Matches[1]) { | ||||
|                         $Qualifiers += "MinLen($($Matches[1]))" | ||||
|                     } | ||||
| @@ -137,10 +171,10 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } | ||||
|             } | ||||
|             'string' { | ||||
|             '^string' { | ||||
|                 $XMLPropertyAttrType.Value = 'string' | ||||
|                 $Qualifiers = @() | ||||
|                 If ($Property.Type -match 'string\((\d*)\.\.(\d*)\)') { | ||||
|                 If ($Property.Type -match '^string\((\d*)\.\.(\d*)\)') { | ||||
|                     If ($Matches[1]) { | ||||
|                         $Qualifiers += "MinLen($($Matches[1]))" | ||||
|                     } | ||||
| @@ -150,7 +184,7 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | ||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||
|                     $XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' ' | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } ElseIf ($Property.Type -match 'string\[(.*)\]') { | ||||
|                 } ElseIf ($Property.Type -match '^string\[(.*)\]') { | ||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||
|                     $XMLPropertyAttrQualifiers.Value = "ValueMap{$($Matches[1] -replace '","', '", "')}" | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|   | ||||
| @@ -1,5 +1,19 @@ | ||||
| DeploymentConfigurations: [] | ||||
| DeploymentConfigurations: | ||||
| - Id: domainmember | ||||
|   Label: Domain member | ||||
|   Description: Windows 10 client joined to an Active Directory domain | ||||
| - Id: standalone | ||||
|   Label: Stand-alone | ||||
|   Description: Stand-alone Windows 10 client | ||||
| PropertyCategories: | ||||
| - Name: 0) Deployment information | ||||
|   ProductProperties: | ||||
|   - Key: deployment.type | ||||
|     Type: string | ||||
|     Value: | ||||
|     - domainmember | ||||
|     - standalone | ||||
|     UserConfigurable: false | ||||
| - Name: 1) Operating System | ||||
|   ProductProperties: | ||||
|   - Key: guestinfo.hostname | ||||
| @@ -7,6 +21,23 @@ PropertyCategories: | ||||
|     Label: Hostname* | ||||
|     Description: '(max length: 15 characters)' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.administratorpw | ||||
|     Type: password(7..) | ||||
|     Label: Local administrator password* | ||||
|     Description: Must meet password complexity rules | ||||
|     DefaultValue: password | ||||
|     Configurations: | ||||
|     - standalone | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.ntpserver | ||||
|     Type: string(1..) | ||||
|     Label: Time server* | ||||
|     Description: A comma-separated list of timeservers | ||||
|     DefaultValue: 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org | ||||
|     Configurations: | ||||
|     - standalone | ||||
|     UserConfigurable: true | ||||
| - Name: 2) Networking | ||||
|   ProductProperties: | ||||
| @@ -15,22 +46,68 @@ PropertyCategories: | ||||
|     Label: IP Address* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.prefixlength | ||||
|     Type: int(8..32) | ||||
|     Label: Subnet prefix length* | ||||
|     Description: '' | ||||
|     DefaultValue: '24' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.dnsserver | ||||
|     Type: ip | ||||
|     Label: DNS server* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.gateway | ||||
|     Type: ip | ||||
|     Label: Gateway* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
| - Name: 3) Active Directory membership | ||||
|   ProductProperties: | ||||
|   - Key: addsconfig.domainname | ||||
|     Type: string(1..) | ||||
|     Label: Domain name* | ||||
|     Description: Must be able to be resolved through provided DNS server | ||||
|     DefaultValue: example.org | ||||
|     Configurations: | ||||
|     - domainmember | ||||
|     UserConfigurable: true | ||||
|   - Key: addsconfig.username | ||||
|     Type: string(1..) | ||||
|     Label: Domain account username* | ||||
|     Description: '' | ||||
|     DefaultValue: username | ||||
|     Configurations: | ||||
|     - domainmember | ||||
|     UserConfigurable: true | ||||
|   - Key: addsconfig.password | ||||
|     Type: password(1..) | ||||
|     Label: Domain account password* | ||||
|     Description: '' | ||||
|     DefaultValue: password | ||||
|     Configurations: | ||||
|     - domainmember | ||||
|     UserConfigurable: true | ||||
| AdvancedOptions: | ||||
| - Key: appliance.name | ||||
|   Value: "{{ appliance.name }}" | ||||
|   Required: false | ||||
| - Key: appliance.version | ||||
|   Value: "{{ appliance.version }}" | ||||
|   Required: false | ||||
|  | ||||
| --- | ||||
| Variables: | ||||
| - Name: appliance.name | ||||
|   Expression: | | ||||
|     $Parameter['appliance.name'] | ||||
| - Name: appliance.version | ||||
|   Expression: | | ||||
|     $Parameter['appliance.version'] | ||||
|   | ||||
| @@ -1,22 +0,0 @@ | ||||
| # Retrieve all respective services (by ID) | ||||
| $GetServiceSplat = @{ | ||||
|     Name = @( | ||||
|         'wuauserv' | ||||
|         'W3SVC', | ||||
|         'XboxGipSvc', | ||||
|         'XblGameSave' | ||||
|     ) | ||||
|     ErrorAction = 'SilentlyContinue' | ||||
| } | ||||
| $Services = Get-Service @GetServiceSplat | ||||
|  | ||||
| # Stop and disable all respective services | ||||
| ForEach ($Service in $Services) { | ||||
|     $SetServiceSplat = @{ | ||||
|         Name        = $Service.Name | ||||
|         Status      = 'Stopped' | ||||
|         StartupType = 'Disabled' | ||||
|         ErrorAction = 'SilentlyContinue' | ||||
|     } | ||||
|     Set-Service @SetServiceSplat | ||||
| } | ||||
| @@ -1,3 +0,0 @@ | ||||
| $nic = get-netadapter | ||||
|  | ||||
| Disable-NetAdapterBinding -InterfaceAlias $nic.name -ComponentID ms_tcpip6 | ||||
| @@ -1,15 +0,0 @@ | ||||
| # Disable monitor timeout (plugged in/battery) | ||||
| #& powercfg /change monitor-timeout-ac 0 | ||||
| #& powercfg /change monitor-timeout-dc 0 | ||||
|  | ||||
| # Disable disk timeout (plugged in/battery) | ||||
| #& powercfg /change disk-timeout-ac 0 | ||||
| #& powercfg /change disk-timeout-dc 0 | ||||
|  | ||||
| # Disable standby timeout (plugged in/battery) | ||||
| & powercfg /change standby-timeout-ac 0 | ||||
| & powercfg /change standby-timeout-dc 0 | ||||
|  | ||||
| # Disable hibernate timeout (plugged in/battery) | ||||
| & powercfg /change hibernate-timeout-ac 0 | ||||
| & powercfg /change hibernate-timeout-dc 0 | ||||
							
								
								
									
										7
									
								
								scripts/Windows10/Register-ScheduledTask.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								scripts/Windows10/Register-ScheduledTask.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     # No parameters | ||||
| ) | ||||
|  | ||||
| # Create scheduled task | ||||
| & schtasks.exe /Create /TN 'FirstBoot' /SC ONSTART /RU SYSTEM /TR "powershell.exe -file C:\Payload\Apply-FirstBootConfig.ps1" | ||||
							
								
								
									
										244
									
								
								scripts/Windows10/payload/Apply-FirstBootConfig.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										244
									
								
								scripts/Windows10/payload/Apply-FirstBootConfig.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,244 @@ | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     # No parameters | ||||
| ) | ||||
|  | ||||
| $SetLocationSplat = @{ | ||||
|     Path = $PSScriptRoot | ||||
| } | ||||
| Set-Location @SetLocationSplat | ||||
|  | ||||
| $NewEventLogSplat = @{ | ||||
|     LogName     = 'Application' | ||||
|     Source      = 'FirstBoot' | ||||
|     ErrorAction = 'SilentlyContinue' | ||||
| } | ||||
| New-EventLog @NewEventLogSplat | ||||
| $WriteEventLogSplat = @{ | ||||
|     LogName   = 'Application' | ||||
|     Source    = 'FirstBoot' | ||||
|     EntryType = 'Information' | ||||
|     EventID   = 1 | ||||
|     Message   = "FirstBoot sequence initiated [working directory: '$PWD']" | ||||
| } | ||||
| Write-EventLog @WriteEventLogSplat | ||||
|  | ||||
| $VMwareToolsExecutable = "C:\Program Files\VMware\VMware Tools\vmtoolsd.exe" | ||||
|  | ||||
| [xml]$ovfEnv = & $VMwareToolsExecutable --cmd "info-get guestinfo.ovfEnv" | Out-String | ||||
| $ovfProperties = $ovfEnv.ChildNodes.NextSibling.PropertySection.Property | ||||
|  | ||||
| $ovfPropertyValues = @{} | ||||
| foreach ($ovfProperty in $ovfProperties) { | ||||
|     $ovfPropertyValues[$ovfProperty.key] = $ovfProperty.Value | ||||
| } | ||||
|  | ||||
| # Check for mandatory values | ||||
| Switch ($ovfPropertyValues['deployment.type']) { | ||||
|     'domainmember' { | ||||
|         $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.gateway', 'addsconfig.domainname', 'addsconfig.username', 'addsconfig.password'), @() | ||||
|     } | ||||
|     'standalone' { | ||||
|         $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.gateway', 'guestinfo.administratorpw', 'guestinfo.ntpserver'), @()         | ||||
|     } | ||||
|     default { | ||||
|         # Mandatory values missing, cannot provision. | ||||
|         $WriteEventLogSplat = @{ | ||||
|             LogName   = 'Application' | ||||
|             Source    = 'FirstBoot' | ||||
|             EntryType = 'Error' | ||||
|             EventID   = 66 | ||||
|             Message   = "Unexpected or no value set for property 'deployment.type', cannot provision." | ||||
|         } | ||||
|         Write-EventLog @WriteEventLogSplat | ||||
|         & schtasks.exe /Change /TN 'FirstBoot' /DISABLE | ||||
|         Stop-Computer -Force | ||||
|         Exit | ||||
|     } | ||||
| } | ||||
| ForEach ($Property in $MandatoryProperties) { | ||||
|     If (!$ovfPropertyValues[$Property]) { | ||||
|         $MissingProperties += $Property | ||||
|     } | ||||
| } | ||||
| If ($MissingProperties.Length -gt 0) { | ||||
|         # Mandatory values missing, cannot provision. | ||||
|         $WriteEventLogSplat = @{ | ||||
|             LogName   = 'Application' | ||||
|             Source    = 'FirstBoot' | ||||
|             EntryType = 'Error' | ||||
|             EventID   = 66 | ||||
|             Message   = "Missing values for mandatory properties $(($MissingProperties | ForEach-Object {"'{0}'" -f $_}) -join ', '), cannot provision." | ||||
|         } | ||||
|         Write-EventLog @WriteEventLogSplat | ||||
|         & schtasks.exe /Change /TN 'FirstBoot' /DISABLE | ||||
|         Stop-Computer -Force | ||||
|         Exit | ||||
| } | ||||
|  | ||||
| # Set hostname and description | ||||
| If ($Env:ComputerName -ne $ovfPropertyValues['guestinfo.hostname']) { | ||||
|     $RenameComputerSplat = @{ | ||||
|         NewName     = $ovfPropertyValues['guestinfo.hostname'] | ||||
|         Force       = $True | ||||
|         Confirm     = $False | ||||
|     } | ||||
|     Rename-Computer @RenameComputerSplat | ||||
|     $SetCimInstanceSplat = @{ | ||||
|         InputObject = (Get-CimInstance -ClassName 'Win32_OperatingSystem') | ||||
|         Property    = @{ | ||||
|             Description = $ovfPropertyValues['guestinfo.hostname'] | ||||
|         } | ||||
|     } | ||||
|     Set-CimInstance  @SetCimInstanceSplat | ||||
|  | ||||
|     # Restart the computer to apply changes | ||||
|     Restart-Computer -Force | ||||
|     Exit | ||||
| } | ||||
|  | ||||
| # Configure network interface | ||||
| If ((Get-WmiObject -Class 'Win32_NetworkAdapterConfiguration').IPAddress -NotContains $ovfPropertyValues['guestinfo.ipaddress']) { | ||||
|     $NewNetIPAddressSplat = @{ | ||||
|         InterfaceAlias = (Get-NetAdapter).Name | ||||
|         AddressFamily  = 'IPv4' | ||||
|         IPAddress      = $ovfPropertyValues['guestinfo.ipaddress'] | ||||
|         PrefixLength   = $ovfPropertyValues['guestinfo.prefixlength'] | ||||
|         DefaultGateway = $ovfPropertyValues['guestinfo.gateway'] | ||||
|     } | ||||
|     $IPAddress = New-NetIPAddress @NewNetIPAddressSplat | ||||
|  | ||||
|     # Wait for network connection to become available | ||||
|     $Timestamp, $TimeoutMinutes = (Get-Date), 5 | ||||
|     Do { | ||||
|         If ($Timestamp.AddMinutes($TimeoutMinutes) -lt (Get-Date)) { | ||||
|             $WriteEventLogSplat = @{ | ||||
|                 LogName   = 'Application' | ||||
|                 Source    = 'FirstBoot' | ||||
|                 EntryType = 'Warning' | ||||
|                 EventID   = 13 | ||||
|                 Message   = "Timeout after $($TimeoutMinutes) minutes waiting for network connection to become available." | ||||
|             } | ||||
|             Write-EventLog @WriteEventLogSplat | ||||
|             Break | ||||
|         } | ||||
|  | ||||
|         Start-Sleep -Milliseconds 250 | ||||
|  | ||||
|         $GetNetIPAddressSplat = @{ | ||||
|             IPAddress      = $ovfPropertyValues['guestinfo.ipaddress'] | ||||
|             InterfaceIndex = $IPAddress.InterfaceIndex | ||||
|             AddressFamily  = 'IPv4' | ||||
|             ErrorAction    = 'SilentlyContinue' | ||||
|         } | ||||
|     } Until ((Get-NetIPAddress @GetNetIPAddressSplat).AddressState -eq 'Preferred') | ||||
|  | ||||
|     $OldErrorActionPreference, $ErrorActionPreference = $ErrorActionPreference, 'SilentlyContinue' | ||||
|     $TestNetConnectionSplat = @{ | ||||
|         ComputerName     = ([IPAddress]$ovfPropertyValues['guestinfo.dnsserver']).IPAddressToString | ||||
|         InformationLevel = 'Quiet' | ||||
|     } | ||||
|     $SetDnsClientServerAddressSplat = @{ | ||||
|         InterfaceAlias  = (Get-NetAdapter).Name | ||||
|         ServerAddresses = If ( | ||||
|             [boolean]($ovfPropertyValues['guestinfo.dnsserver'] -as [IPaddress]) -and (Test-NetConnection @TestNetConnectionSplat)) { | ||||
|                 ($ovfPropertyValues['guestinfo.dnsserver']) | ||||
|             } else { | ||||
|                 ('127.0.0.1') | ||||
|             } | ||||
|         Validate        = $False | ||||
|     } | ||||
|     Set-DnsClientServerAddress @SetDnsClientServerAddressSplat | ||||
|     $ErrorActionPreference, $OldErrorActionPreference = $OldErrorActionPreference, $NULL | ||||
| } | ||||
|  | ||||
| Switch ($ovfPropertyValues['deployment.type']) { | ||||
|     'domainmember' { | ||||
|         # Join Active Directory domain as member | ||||
|         If (!(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) { | ||||
|             $AddComputerSplat = @{ | ||||
|                 DomainName = $ovfPropertyValues['addsconfig.domainname'] | ||||
|                 Credential = New-Object System.Management.Automation.PSCredential( | ||||
|                     $ovfPropertyValues['addsconfig.username'], | ||||
|                     (ConvertTo-SecureString $ovfPropertyValues['addsconfig.password'] -AsPlainText -Force) | ||||
|                 ) | ||||
|                 # OUPath     = $ovfPropertyValues['addsconfig.organizationalunit'] | ||||
|                 Restart    = $True | ||||
|                 Force      = $True | ||||
|                 Confirm    = $False | ||||
|             } | ||||
|             Add-Computer @AddComputerSplat | ||||
|  | ||||
|             # Previous cmdlet performs a reboot on completion; so these are commented out | ||||
|             # Restart-Computer -Force | ||||
|             # Exit | ||||
|         } | ||||
|     } | ||||
|     'standalone' { | ||||
|         # Change password of built-in Administrator | ||||
|         $BuiltinAdministrator = (Get-LocalUser | Where-Object {$_.SID -match '-500'}) | ||||
|         $ConvertToSecureStringSplat = @{ | ||||
|             String      = $ovfPropertyValues['guestinfo.administratorpw'] | ||||
|             AsPlainText = $True | ||||
|             Force       = $True | ||||
|         } | ||||
|         $SetLocalUserSplat = @{ | ||||
|             InputObject           = $BuiltinAdministrator | ||||
|             Password              = ConvertTo-SecureString @ConvertToSecureStringSplat | ||||
|             PasswordNeverExpires  = $True | ||||
|             AccountNeverExpires   = $True | ||||
|             ### This setting is not allowed on the last administrator | ||||
|             # UserMayChangePassword = $False | ||||
|             Confirm               = $False | ||||
|         } | ||||
|         Set-LocalUser @SetLocalUserSplat | ||||
|  | ||||
|         $EnableLocalUserSplat = @{ | ||||
|             InputObject = $BuiltinAdministrator | ||||
|             Confirm     = $False | ||||
|         } | ||||
|         Enable-LocalUser @EnableLocalUserSplat | ||||
|     } | ||||
| } | ||||
|  | ||||
| # Iterate through and invoke all payload scripts | ||||
| #! TODO: add registry values to determine which scripts have already been invoked (in case of intermediate reboots) | ||||
| $GetItemSplat = @{ | ||||
|     Path = "$($PSScriptRoot)\Scripts\*.ps1" | ||||
| } | ||||
| ForEach ($Script in (Get-Item @GetItemSplat)) { | ||||
|     Try { | ||||
|         $WriteEventLogSplat = @{ | ||||
|             LogName   = 'Application' | ||||
|             Source    = 'FirstBoot' | ||||
|             EntryType = 'Information' | ||||
|             EventID   = 4 | ||||
|             Message   = "Running script: '$($Script.FullName)'" | ||||
|         } | ||||
|         Write-EventLog @WriteEventLogSplat | ||||
|         & $Script.FullName -Parameter $ovfPropertyValues | ||||
|     } | ||||
|     Catch { | ||||
|         $WriteEventLogSplat = @{ | ||||
|             LogName   = 'Application' | ||||
|             Source    = 'FirstBoot' | ||||
|             EntryType = 'Error' | ||||
|             EventID   = 66 | ||||
|             Message   = @" | ||||
| Error occurred while executing script '$($Script.Name)': | ||||
| $($_.Exception.Message) | ||||
| "@ | ||||
|         } | ||||
|         Write-EventLog @WriteEventLogSplat | ||||
|     } | ||||
| } | ||||
|  | ||||
| $WriteEventLogSplat = @{ | ||||
|     LogName   = 'Application' | ||||
|     Source    = 'FirstBoot' | ||||
|     EntryType = 'Information' | ||||
|     EventID   = 42 | ||||
|     Message   = 'FirstBoot sequence applied and finished' | ||||
| } | ||||
| Write-EventLog @WriteEventLogSplat | ||||
| & schtasks.exe /Change /TN 'FirstBoot' /DISABLE | ||||
		Reference in New Issue
	
	Block a user