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 | type: kubernetes | ||||||
| name: 'Packer Build' | name: 'Packer Build' | ||||||
|      |      | ||||||
|  | volumes: | ||||||
|  | - name: output | ||||||
|  |   claim: | ||||||
|  |     name: flexvolsmb-drone-output | ||||||
|  | - name: scratch | ||||||
|  |   claim: | ||||||
|  |     name: flexvolsmb-drone-scratch | ||||||
|  |  | ||||||
| steps: | steps: | ||||||
|  | - name: Debugging information | ||||||
|  |   image: bv11-cr01.bessems.eu/library/packer-extended | ||||||
|  |   commands: | ||||||
|  |   - yamllint --version | ||||||
|  |   - packer --version | ||||||
|  |   - pwsh --version | ||||||
|  |   - ovftool --version | ||||||
| - name: Windows 10 | - name: Windows 10 | ||||||
|   image: bv11-cr01.bessems.eu/library/packer-extended |   image: bv11-cr01.bessems.eu/library/packer-extended | ||||||
|  |   pull: always | ||||||
|   commands: |   commands: | ||||||
|   - sed -i -e "s/<<img-productkey>>/$${PRODUCTKEY}/" packer/preseed/Windows10/Autounattend.xml |   - sed -i -e "s/<<img-productkey>>/$${PRODUCTKEY}/" packer/preseed/Windows10/Autounattend.xml | ||||||
|   - | |   - | | ||||||
|     sed -i -e "s/<<img-password>>/$${WINRM_PASSWORD}/g" \ |     sed -i -e "s/<<img-password>>/$${WINRM_PASSWORD}/g" \ | ||||||
|       packer/preseed/Windows10/Autounattend.xml \ |       packer/preseed/Windows10/Autounattend.xml \ | ||||||
|       packer/preseed/Windows10/Sysprep_Unattend.xml |       packer/preseed/Windows10/Sysprep_Unattend.xml | ||||||
|  |   - | | ||||||
|  |     yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts | ||||||
|  |   - | | ||||||
|  |     packer init -upgrade \ | ||||||
|  |       ./packer | ||||||
|   - | |   - | | ||||||
|     packer validate \ |     packer validate \ | ||||||
|       -var-file=packer/variables.vsphere.json \ |       -var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ | ||||||
|       -var vm_name=${DRONE_COMMIT_SHA:0:10}-$DRONE_BUILD_NUMBER \ |  | ||||||
|       -var vm_guestos=win10 \ |       -var vm_guestos=win10 \ | ||||||
|       -var repo_username=$${REPO_USERNAME} \ |       -var repo_username=$${REPO_USERNAME} \ | ||||||
|       -var repo_password=$${REPO_PASSWORD} \ |       -var repo_password=$${REPO_PASSWORD} \ | ||||||
|       -var vsphere_password=$${VSPHERE_PASSWORD} \ |       -var vsphere_password=$${VSPHERE_PASSWORD} \ | ||||||
|       -var winrm_password=$${WINRM_PASSWORD} \ |       -var winrm_password=$${WINRM_PASSWORD} \ | ||||||
|       packer/windows10.json \ |       ./packer | ||||||
|   - | |   - | | ||||||
|     packer build \ |     packer build \ | ||||||
|       -on-error=cleanup \ |       -on-error=cleanup \ | ||||||
|       -var-file=packer/variables.vsphere.json \ |       -var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ | ||||||
|       -var vm_name=${DRONE_COMMIT_SHA:0:10}-$DRONE_BUILD_NUMBER \ |  | ||||||
|       -var vm_guestos=win10 \ |       -var vm_guestos=win10 \ | ||||||
|       -var repo_username=$${REPO_USERNAME} \ |       -var repo_username=$${REPO_USERNAME} \ | ||||||
|       -var repo_password=$${REPO_PASSWORD} \ |       -var repo_password=$${REPO_PASSWORD} \ | ||||||
|       -var vsphere_password=$${VSPHERE_PASSWORD} \ |       -var vsphere_password=$${VSPHERE_PASSWORD} \ | ||||||
|       -var winrm_password=$${WINRM_PASSWORD} \ |       -var winrm_password=$${WINRM_PASSWORD} \ | ||||||
|       packer/windows10.json \ |       ./packer | ||||||
|   environment: |   environment: | ||||||
|     VSPHERE_PASSWORD: |     VSPHERE_PASSWORD: | ||||||
|       from_secret: vsphere_password |       from_secret: vsphere_password | ||||||
| @@ -47,8 +66,22 @@ steps: | |||||||
|   volumes: |   volumes: | ||||||
|   - name: output |   - name: output | ||||||
|     path: /output |     path: /output | ||||||
|  | - name: Remove temporary resources | ||||||
| volumes: |   image: bv11-cr01.bessems.eu/library/packer-extended | ||||||
| - name: output |   commands: | ||||||
|   claim: |   - | | ||||||
|     name: flexvolsmb-drone-output |     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> |                     <InstallFrom> | ||||||
|                         <MetaData wcm:action="add"> |                         <MetaData wcm:action="add"> | ||||||
|                             <Key>/IMAGE/INDEX</Key> |                             <Key>/IMAGE/INDEX</Key> | ||||||
|                             <Value>6</Value> |                             <Value>3</Value> | ||||||
|                         </MetaData> |                         </MetaData> | ||||||
|                     </InstallFrom> |                     </InstallFrom> | ||||||
|                 </OSImage> |                 </OSImage> | ||||||
|   | |||||||
| @@ -31,21 +31,11 @@ | |||||||
|             <TimeZone>UTC</TimeZone> |             <TimeZone>UTC</TimeZone> | ||||||
|             <UserAccounts> |             <UserAccounts> | ||||||
|                 <AdministratorPassword> |                 <AdministratorPassword> | ||||||
|                     <Value>secret</Value> |                     <Value><<img-password>></Value> | ||||||
|                     <PlainText>true</PlainText> |                     <PlainText>true</PlainText> | ||||||
|                 </AdministratorPassword> |                 </AdministratorPassword> | ||||||
|             </UserAccounts> |             </UserAccounts> | ||||||
|         </component> |         </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> | ||||||
|     <settings pass="specialize"> |     <settings pass="specialize"> | ||||||
|     </settings> |     </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 | Connect-VIServer @ConnectVIServerSplat | Out-Null | ||||||
|  |  | ||||||
| $RemoveVMSplat = @{ | $GetVMSplat = @{ | ||||||
|     VM                       = "$($VMName)*" |     Name        = "*$($VMName)*" | ||||||
|  |     ErrorAction = 'SilentlyContinue' | ||||||
|  | } | ||||||
|  | If ([boolean](Get-VM @GetVMSplat)) { | ||||||
|  |     $RemoveVMSplat = @{ | ||||||
|  |         VM                       = Get-VM @GetVMSplat | ||||||
|         DeletePermanently        = $True |         DeletePermanently        = $True | ||||||
|         Confirm                  = $False |         Confirm                  = $False | ||||||
|         ErrorAction              = 'SilentlyContinue' |         ErrorAction              = 'SilentlyContinue' | ||||||
|  |     } | ||||||
|  |     Remove-VM @RemoveVMSplat | ||||||
| } | } | ||||||
| Remove-VM @RemoveVMSplat |  | ||||||
|  |  | ||||||
| # Also delete ISO/floppy? |  | ||||||
|  |  | ||||||
| Disconnect-VIServer * -Confirm:$False | 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." |                 Throw "'$_' is not a valid filename (within working directory '$PWD'), or access denied; aborting." | ||||||
|             } |             } | ||||||
|         })] |         })] | ||||||
|     [string]$OVFFile |     [string]$OVFFile, | ||||||
|  |     [hashtable]$Parameter | ||||||
| ) | ) | ||||||
|  |  | ||||||
| $GetContentSplat = @{ | $GetContentSplat = @{ | ||||||
| @@ -21,7 +22,24 @@ $ConvertFromYamlSplat = @{ | |||||||
|     Yaml         = $RawContent |     Yaml         = $RawContent | ||||||
|     AllDocuments = $True |     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 | $SourceFile = Get-Item -Path $OVFFile | ||||||
| $GetContentSplat = @{ | $GetContentSplat = @{ | ||||||
| @@ -62,6 +80,22 @@ If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { | |||||||
| $XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) | $XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) | ||||||
| $XMLAttrTransport.Value = 'com.vmware.guestInfo' | $XMLAttrTransport.Value = 'com.vmware.guestInfo' | ||||||
| [void]$XML.SelectSingleNode('//Any:VirtualHardwareSection', $NS).Attributes.Append($XMLAttrTransport) | [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) | $XMLProductSection = $XML.SelectSingleNode('//Any:ProductSection', $NS) | ||||||
| If ($XMLProductSection -eq $Null) { | If ($XMLProductSection -eq $Null) { | ||||||
| @@ -94,13 +128,13 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | |||||||
|         $XMLPropertyAttrKey.Value = $Property.Key |         $XMLPropertyAttrKey.Value = $Property.Key | ||||||
|         $XMLPropertyAttrType = $XML.CreateAttribute('type', $XML.DocumentElement.ovf) |         $XMLPropertyAttrType = $XML.CreateAttribute('type', $XML.DocumentElement.ovf) | ||||||
|         Switch -regex ($Property.Type) { |         Switch -regex ($Property.Type) { | ||||||
|             'boolean' { |             '^boolean' { | ||||||
|                 $XMLPropertyAttrType.Value = 'boolean' |                 $XMLPropertyAttrType.Value = 'boolean' | ||||||
|             } |             } | ||||||
|             'int' { |             '^int' { | ||||||
|                 $XMLPropertyAttrType.Value = 'uint8' |                 $XMLPropertyAttrType.Value = 'uint8' | ||||||
|                 $Qualifiers = @() |                 $Qualifiers = @() | ||||||
|                 If ($Property.Type -match 'int\((\d*)\.\.(\d*)\)') { |                 If ($Property.Type -match '^int\((\d*)\.\.(\d*)\)') { | ||||||
|                     If ($Matches[1]) { |                     If ($Matches[1]) { | ||||||
|                         $Qualifiers += "MinValue($($Matches[1]))" |                         $Qualifiers += "MinValue($($Matches[1]))" | ||||||
|                     } |                     } | ||||||
| @@ -112,20 +146,20 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | |||||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) |                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             'ip' { |             '^ip' { | ||||||
|                 $XMLPropertyAttrType.Value = 'string' |                 $XMLPropertyAttrType.Value = 'string' | ||||||
|                 $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.vmw) |                 $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.vmw) | ||||||
|                 $XMLPropertyAttrQualifiers.Value = 'Ip' |                 $XMLPropertyAttrQualifiers.Value = 'Ip' | ||||||
|                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) |                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||||
|             } |             } | ||||||
|             'password' { |             '^password' { | ||||||
|                 $XMLPropertyAttrType.Value = 'string' |                 $XMLPropertyAttrType.Value = 'string' | ||||||
|                 $XMLPropertyAttrPassword = $XML.CreateAttribute('password', $XML.DocumentElement.ovf) |                 $XMLPropertyAttrPassword = $XML.CreateAttribute('password', $XML.DocumentElement.ovf) | ||||||
|                 $XMLPropertyAttrPassword.Value = 'true' |                 $XMLPropertyAttrPassword.Value = 'true' | ||||||
|                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrPassword) |                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrPassword) | ||||||
|  |  | ||||||
|                 $Qualifiers = @() |                 $Qualifiers = @() | ||||||
|                 If ($Property.Type -match 'password\((\d*)\.\.(\d*)\)') { |                 If ($Property.Type -match '^password\((\d*)\.\.(\d*)\)') { | ||||||
|                     If ($Matches[1]) { |                     If ($Matches[1]) { | ||||||
|                         $Qualifiers += "MinLen($($Matches[1]))" |                         $Qualifiers += "MinLen($($Matches[1]))" | ||||||
|                     } |                     } | ||||||
| @@ -137,10 +171,10 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | |||||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) |                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             'string' { |             '^string' { | ||||||
|                 $XMLPropertyAttrType.Value = 'string' |                 $XMLPropertyAttrType.Value = 'string' | ||||||
|                 $Qualifiers = @() |                 $Qualifiers = @() | ||||||
|                 If ($Property.Type -match 'string\((\d*)\.\.(\d*)\)') { |                 If ($Property.Type -match '^string\((\d*)\.\.(\d*)\)') { | ||||||
|                     If ($Matches[1]) { |                     If ($Matches[1]) { | ||||||
|                         $Qualifiers += "MinLen($($Matches[1]))" |                         $Qualifiers += "MinLen($($Matches[1]))" | ||||||
|                     } |                     } | ||||||
| @@ -150,7 +184,7 @@ ForEach ($Category in $OVFConfig.PropertyCategories) { | |||||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) |                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||||
|                     $XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' ' |                     $XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' ' | ||||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) |                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||||
|                 } ElseIf ($Property.Type -match 'string\[(.*)\]') { |                 } ElseIf ($Property.Type -match '^string\[(.*)\]') { | ||||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) |                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||||
|                     $XMLPropertyAttrQualifiers.Value = "ValueMap{$($Matches[1] -replace '","', '", "')}" |                     $XMLPropertyAttrQualifiers.Value = "ValueMap{$($Matches[1] -replace '","', '", "')}" | ||||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) |                     [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: | PropertyCategories: | ||||||
|  | - Name: 0) Deployment information | ||||||
|  |   ProductProperties: | ||||||
|  |   - Key: deployment.type | ||||||
|  |     Type: string | ||||||
|  |     Value: | ||||||
|  |     - domainmember | ||||||
|  |     - standalone | ||||||
|  |     UserConfigurable: false | ||||||
| - Name: 1) Operating System | - Name: 1) Operating System | ||||||
|   ProductProperties: |   ProductProperties: | ||||||
|   - Key: guestinfo.hostname |   - Key: guestinfo.hostname | ||||||
| @@ -7,6 +21,23 @@ PropertyCategories: | |||||||
|     Label: Hostname* |     Label: Hostname* | ||||||
|     Description: '(max length: 15 characters)' |     Description: '(max length: 15 characters)' | ||||||
|     DefaultValue: '' |     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 |     UserConfigurable: true | ||||||
| - Name: 2) Networking | - Name: 2) Networking | ||||||
|   ProductProperties: |   ProductProperties: | ||||||
| @@ -15,22 +46,68 @@ PropertyCategories: | |||||||
|     Label: IP Address* |     Label: IP Address* | ||||||
|     Description: '' |     Description: '' | ||||||
|     DefaultValue: '' |     DefaultValue: '' | ||||||
|  |     Configurations: '*' | ||||||
|     UserConfigurable: true |     UserConfigurable: true | ||||||
|   - Key: guestinfo.prefixlength |   - Key: guestinfo.prefixlength | ||||||
|     Type: int(8..32) |     Type: int(8..32) | ||||||
|     Label: Subnet prefix length* |     Label: Subnet prefix length* | ||||||
|     Description: '' |     Description: '' | ||||||
|     DefaultValue: '24' |     DefaultValue: '24' | ||||||
|  |     Configurations: '*' | ||||||
|     UserConfigurable: true |     UserConfigurable: true | ||||||
|   - Key: guestinfo.dnsserver |   - Key: guestinfo.dnsserver | ||||||
|     Type: ip |     Type: ip | ||||||
|     Label: DNS server* |     Label: DNS server* | ||||||
|     Description: '' |     Description: '' | ||||||
|     DefaultValue: '' |     DefaultValue: '' | ||||||
|  |     Configurations: '*' | ||||||
|     UserConfigurable: true |     UserConfigurable: true | ||||||
|   - Key: guestinfo.gateway |   - Key: guestinfo.gateway | ||||||
|     Type: ip |     Type: ip | ||||||
|     Label: Gateway* |     Label: Gateway* | ||||||
|     Description: '' |     Description: '' | ||||||
|     DefaultValue: '' |     DefaultValue: '' | ||||||
|  |     Configurations: '*' | ||||||
|     UserConfigurable: true |     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