12 Commits
Author SHA1 Message Date
djpbessems b4f62b465d Update packer windows-update plugin
continuous-integration/drone/push Build is passing
2021-10-25 13:32:57 +02:00
djpbessems 060ac37dc0 Update VMware Tools 2021-10-25 13:12:00 +02:00
djpbessems b75694479a Migrate to HCL;Add 'packer init' step;Add variable definitions;Add debugging information
continuous-integration/drone/push Build is passing
2021-06-05 19:34:31 +02:00
djpbessems b304a17ee1 Change to Windows 10 Enterprise #2
continuous-integration/drone/push Build is passing
2021-04-11 18:23:23 +02:00
djpbessems d155db26e7 Change to Windows 10 Enterprise
continuous-integration/drone/push Build is failing
2021-04-11 18:13:00 +02:00
djpbessems b2f607e2b5 Enable builtin administrator (override default sysprep behaviour)
continuous-integration/drone/push Build is passing
2021-04-11 11:46:22 +02:00
djpbessems 465088b455 Fix staging directory
continuous-integration/drone/push Build is passing
2021-04-10 16:47:47 +02:00
djpbessems 3db5e7dbf7 Update hypervisor FQDN
continuous-integration/drone/push Build is failing
2021-04-10 15:35:15 +02:00
djpbessems f84e065e15 Add pull policy
continuous-integration/drone/push Build is failing
2021-04-10 15:34:04 +02:00
djpbessems 00557e50f9 Replay sidestream changes
continuous-integration/drone/push Build is failing
2021-04-10 15:32:31 +02:00
djpbessems e455419986 Update badge in README 2021-01-27 21:32:42 +01:00
djpbessems 08b63f30d6 Delete commit history (containing proprietary code)
continuous-integration/drone/push Build is passing
2021-01-24 09:26:53 +01:00
54 changed files with 461 additions and 934 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 KiB

+9 -24
View File
@@ -13,22 +13,20 @@ volumes:
steps: steps:
- name: Debugging information - name: Debugging information
image: bv11-cr01.bessems.eu/library/packer-extended image: bv11-cr01.bessems.eu/library/packer-extended
pull: always
commands: commands:
- yamllint --version - yamllint --version
- packer --version - packer --version
- qemu-img --version
- ovftool --version
- pwsh --version - pwsh --version
- name: Windows Server 2019 - ovftool --version
- name: Windows 10
image: bv11-cr01.bessems.eu/library/packer-extended image: bv11-cr01.bessems.eu/library/packer-extended
pull: always pull: always
commands: commands:
- sed -i -e "s/<<img-productkey>>/$${PRODUCTKEY}/" packer/preseed/Server2019/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/Server2019/Autounattend.xml \ packer/preseed/Windows10/Autounattend.xml \
packer/preseed/Server2019/Sysprep_Unattend.xml packer/preseed/Windows10/Sysprep_Unattend.xml
- | - |
yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts
- | - |
@@ -37,7 +35,7 @@ steps:
- | - |
packer validate \ packer validate \
-var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ -var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \
-var vm_guestos=server2019 \ -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} \
@@ -45,9 +43,9 @@ steps:
./packer ./packer
- | - |
packer build \ packer build \
-on-error=cleanup -timestamp-ui \ -on-error=cleanup \
-var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \ -var vm_name=$DRONE_BUILD_NUMBER-${DRONE_COMMIT_SHA:0:10} \
-var vm_guestos=server2019 \ -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} \
@@ -63,16 +61,13 @@ steps:
REPO_PASSWORD: REPO_PASSWORD:
from_secret: repo_password from_secret: repo_password
PRODUCTKEY: PRODUCTKEY:
from_secret: prodkey_server2019 from_secret: prodkey_win10
# PACKER_LOG: 1 # PACKER_LOG: 1
volumes: volumes:
- name: output - name: output
path: /output path: /output
- name: scratch
path: /scratch
- name: Remove temporary resources - name: Remove temporary resources
image: bv11-cr01.bessems.eu/library/packer-extended image: bv11-cr01.bessems.eu/library/packer-extended
pull: always
commands: commands:
- | - |
pwsh -file scripts/Remove-Resources.ps1 \ pwsh -file scripts/Remove-Resources.ps1 \
@@ -90,13 +85,3 @@ steps:
status: status:
- success - success
- failure - failure
- name: Trigger downstream builds
image: plugins/downstream
settings:
server: https://ci.spamasaurus.com
token:
from_secret: drone_token
fork: true
repositories:
- djpbessems/Packer.Images@ADCS
- djpbessems/Packer.Images@ADDS
+1 -85
View File
@@ -1,85 +1 @@
# Packer.Images [![Build Status](https://ci.spamasaurus.com/api/badges/djpbessems/Packer.Images/status.svg?ref=refs/heads/Server2019)](https://ci.spamasaurus.com/djpbessems/Packer.Images) # Packer.Images [![Build Status](https://ci.spamasaurus.com/api/badges/djpbessems/Packer.Images/status.svg?ref=refs/heads/Windows10)](https://ci.spamasaurus.com/djpbessems/Packer.Images)
This OVA appliance allows deploying a Windows Server fully automated; either as a domain member or stand-alone server.
The included `.ovf` file has the following XML contents (simplified for clarity) to facilitate the different `DeploymentOption`s:
```xml
<Envelope [...]>
[...]
<DeploymentOptionSection>
<Info>Deployment Type</Info>
<Configuration ovf:id="domainmember">
<Label>Domain member</Label>
<Description>Windows Server joined to an Active Directory domain</Description>
</Configuration>
<Configuration ovf:id="standalone">
<Label>Stand-alone</Label>
<Description>Stand-alone Windows Server</Description>
</Configuration>
</DeploymentOptionSection>
<VirtualSystem ovf:id="[...]">
[...]
<ProductSection>
[...]
<Category>1) Operating System</Category>
<Property ovf:configuration="domainmember standalone" ovf:key="guestinfo.hostname" [...]>
<Label>Hostname*</Label>
</Property>
<Property ovf:configuration="standalone" ovf:key="guestinfo.administratorpw" [...]>
<Label>Local administrator password*</Label>
</Property>
[...]
<Category>3) Active Directory membership</Category>
<Property ovf:configuration="domainmember" ovf:key="addsconfig.domainname" [...]>
<Label>Domain name*</Label>
</Property>
<Property ovf:configuration="domainmember" ovf:key="addsconfig.username" [...]>
<Label>Domain account username*</Label>
</Property>
<Property ovf:configuration="domainmember" ovf:key="addsconfig.password" [...]>
<Label>Domain account password*</Label>
</Property>
</ProductSection>
</VirtualSystem>
</Envelope>
```
When **provisioning** the appliance through the vCenter 'Deploy OVF template...' wizard, or through vApp-compatible *Infrastructure as code* tooling (e.g. HashiCorp Terraform), it is possible to provide all relevant configuration through vApp properties.
<table>
<tr>
<td><em>vSphere 'Deploy OVF template...' wizard</em></td> <td> <a href="https://registry.terraform.io/providers/hashicorp/vsphere/latest/docs/resources/virtual_machine#deploying-vm-from-an-ovfova-template">HashiCorp Terraform vSphere provider</a> </td>
</tr>
<tr>
<td><img src=".assets/vAppConfigurations-Server2019-example.png" alt="vApp properties" width="400" /><br/><img src=".assets/vAppProperties-Server2019-example.png" alt="vApp properties" width="400" /></td>
<td>
```hcl
vapp {
properties = {
# "deployment.type" = "domainmember"
"guestinfo.hostname" = "SRV01"
# "guestinfo.administratorpw" = var.vm_adminpassword
# "guestinfo.ntpserver" = "0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org"
"guestinfo.ipaddress" = "10.0.0.42"
"guestinfo.prefixlength" = "24"
"guestinfo.dnsserver" = "10.0.0.21"
"guestinfo.gateway" = "10.0.0.1"
"addsconfig.domainname" = "contoso.com"
"addsconfig.username" = "CONTOSO\\domainjoin"
"addsconfig.password" = var.adds_password
}
}
```
</td>
</tr>
</table>
On first boot, the appliance will start **configuring** itself without any further user-input, by performing the following steps:
- Change hostname
- Configure network
- Join Active Directory domain **-OR-** Set password for local administrator
- Iterate through any payload scripts
@@ -0,0 +1,16 @@
script = <<-EOH
$nic = get-netadapter
Get-NetAdapterBinding –InterfaceAlias $nic.name –ComponentID ms_tcpip6
EOH
control "ipv6" do
title 'Disabled network protocol IPv6'
desc '
This test assures that IPv6 is disabled
'
describe powershell(script) do
its('stdout') { should match 'False' }
end
end
@@ -0,0 +1,29 @@
script = <<-EOH
# Initialize variable to empty array
$NonCompliantServices = @()
# Specify relevant services
$Services = @(
"wuauserv",
"W3SVC",
"XboxGipSvc",
"XblGameSave"
)
# Enumerate all services
$NonCompliantServices += Get-Service $Services -ErrorAction 'SilentlyContinue' | Where-Object {$_.StartType -ne 'Disabled'}
# Output; 'True' or list of noncompliant services
Write-Output ($True, $NonCompliantServices)[!($NonCompliantServices.Count -eq 0)]
EOH
control "disabled_services" do
title 'Disabled services'
desc '
This test assures that all unneeded services are set to "disabled".
'
describe powershell(script) do
its('stdout') { should match 'True' }
end
end
@@ -0,0 +1,29 @@
script = <<-EOH
# Initialize variable to empty array
$LogicalDisks = @()
# Enumerate all logicaldisks
# DriveType:
# Unknown (0)
# No Root Directory (1)
# Removable Disk (2)
# Local Disk (3)
# Network Drive (4)
# Compact Disc (5)
# RAM Disk (6)
$LogicalDisks += Get-WmiObject -Class 'win32_logicaldisk' -Filter 'DriveType=3'
# Filter/Quantify
($LogicalDisks.Count -eq 1) -and (($LogicalDisks | Where-Object {$_.DeviceID -ne 'C:'}).Count -eq 0)
EOH
control "single_disk" do
title 'Single Disk'
desc '
This test assures that only a single disk (C:) is available
'
describe powershell(script) do
its('stdout') { should match 'True' }
end
end
@@ -0,0 +1,54 @@
control "software_installed-7zip" do
title 'Included Default Applications: 7-Zip'
desc '
This test assures that the software application "7-Zip" is installed.
'
describe chocolatey_package('7zip.install') do
it { should be_installed }
end
end
# control "software_installed-dotnetfx" do
# title 'Included Default Applications: .NET'
# desc '
# This test assures that the software application ".NET" is installed.
# '
# describe chocolatey_package('dotnetfx') do
# it { should be_installed }
# end
# end
# control "software_installed-foxitreader" do
# title 'Included Default Applications: Foxit Reader'
# desc '
# This test assures that the software application "Foxit Reader" is installed.
# '
# describe chocolatey_package('foxitreader') do
# it { should be_installed }
# end
# end
# control "software_installed-notepadplusplus" do
# title 'Included Default Applications: Notepad++'
# desc '
# This test assures that the software application "Notepad++" is installed.
# '
# describe chocolatey_package('notepadplusplus') do
# it { should be_installed }
# end
# end
# control "software_installed-putty" do
# title 'Included Default Applications: Putty'
# desc '
# This test assures that the software application "PuTTy" is installed.
# '
# describe chocolatey_package('putty') do
# it { should be_installed }
# end
# end
@@ -0,0 +1,10 @@
---
name: Windows 10 IoT Enterprise
title: Windows 10 IoT Enterprise InSpec Tests
summary: Unit test for Windows 10 IoT Enterprise
version: 1.0.0
maintainer: https://code.spamasaurus.com/djpbessems
copyright: https://code.spamasaurus.com/djpbessems
license: Proprietary
supports:
- platform-family: windows
-5
View File
@@ -1,5 +0,0 @@
iso_url = "sn.itch.fyi/Repository/iso/Microsoft/Windows%20Server%202019/LTSC/en_windows_server_2019_x64_dvd_4cb967d8.iso"
iso_checksum = "sha256:4c5dd63efee50117986a2e38d4b3a3fbaf3c1c15e2e7ea1d23ef9d8af148dd2d"
iso_paths = [
"ISO-files/VMware-tools-windows-11.2.1-17243207/VMware-tools-windows-11.2.1-17243207.iso"
]
@@ -1,168 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<servicing/>
<settings pass="auditSystem">
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DriverPaths>
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
<Path>E:\Program Files\VMware\VMware Tools\Drivers\pvscsi\Win8\amd64</Path>
</PathAndCredentials>
</DriverPaths>
</component>
</settings>
<settings pass="windowsPE">
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DiskConfiguration>
<Disk wcm:action="add">
<CreatePartitions>
<CreatePartition wcm:action="add">
<Order>1</Order>
<Type>Primary</Type>
<Extend>true</Extend>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<ModifyPartition wcm:action="add">
<Extend>false</Extend>
<Format>NTFS</Format>
<Letter>C</Letter>
<Order>1</Order>
<PartitionID>1</PartitionID>
<Label>Windows Server 2019</Label>
</ModifyPartition>
</ModifyPartitions>
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
</Disk>
<WillShowUI>OnError</WillShowUI>
</DiskConfiguration>
<UserData>
<AcceptEula>true</AcceptEula>
<!-- <FullName>Spamasaurus Rex</FullName>
<Organization>Spamasaurus Rex</Organization> -->
<ProductKey>
<Key><<img-productkey>></Key>
<WillShowUI>Never</WillShowUI>
</ProductKey>
</UserData>
<ImageInstall>
<OSImage>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>1</PartitionID>
</InstallTo>
<WillShowUI>OnError</WillShowUI>
<InstallToAvailablePartition>false</InstallToAvailablePartition>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/INDEX</Key>
<Value>4</Value>
</MetaData>
</InstallFrom>
</OSImage>
</ImageInstall>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<InputLocale>en-US</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>en-US</UserLocale>
</component>
</settings>
<settings pass="offlineServicing">
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<EnableLUA>false</EnableLUA>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-International-Core" 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">
<InputLocale>en-US</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UserLocale>en-US</UserLocale>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<UserAccounts>
<AdministratorPassword>
<Value><<img-password>></Value>
<PlainText>true</PlainText>
</AdministratorPassword>
</UserAccounts>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Home</NetworkLocation>
<ProtectYourPC>1</ProtectYourPC>
</OOBE>
<AutoLogon>
<Password>
<Value><<img-password>></Value>
<PlainText>true</PlainText>
</Password>
<Username>administrator</Username>
<Enabled>true</Enabled>
</AutoLogon>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
<Description>Set execution policy 64bit</Description>
<Order>1</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>C:\Windows\SysWOW64\cmd.exe /c powershell -Command "Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force"</CommandLine>
<Description>Set execution policy 32bit</Description>
<Order>2</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c reg add "HKLM\System\CurrentControlSet\Control\Network\NewNetworkWindowOff"</CommandLine>
<Description>Disable new network prompt</Description>
<Order>3</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\Set-NetworkProfile.ps1</CommandLine>
<Description>Set network profile to private</Description>
<Order>4</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\Disable-WinRM.ps1</CommandLine>
<Description>Disable WinRM</Description>
<Order>5</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c a:\Install-VMwareTools.cmd</CommandLine>
<Order>13</Order>
<Description>Install VMware Tools</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -File a:\Enable-WinRM.ps1</CommandLine>
<Description>Enable WinRM</Description>
<Order>99</Order>
</SynchronousCommand>
</FirstLogonCommands>
<ShowWindowsLive>false</ShowWindowsLive>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<OEMInformation>
<HelpCustomized>false</HelpCustomized>
</OEMInformation>
<!-- Rename computer here. -->
<ComputerName>packer-template</ComputerName>
<TimeZone>W. Europe Standard Time</TimeZone>
<RegisteredOwner/>
</component>
<component xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SkipAutoActivation>true</SkipAutoActivation>
</component>
</settings>
</unattend>
@@ -19,7 +19,7 @@
<Letter>C</Letter> <Letter>C</Letter>
<Order>1</Order> <Order>1</Order>
<PartitionID>1</PartitionID> <PartitionID>1</PartitionID>
<Label>Windows Server 2019</Label> <Label>Windows 10</Label>
</ModifyPartition> </ModifyPartition>
</ModifyPartitions> </ModifyPartitions>
<DiskID>0</DiskID> <DiskID>0</DiskID>
@@ -47,7 +47,7 @@
<InstallFrom> <InstallFrom>
<MetaData wcm:action="add"> <MetaData wcm:action="add">
<Key>/IMAGE/INDEX</Key> <Key>/IMAGE/INDEX</Key>
<Value>4</Value> <Value>3</Value>
</MetaData> </MetaData>
</InstallFrom> </InstallFrom>
</OSImage> </OSImage>
-9
View File
@@ -3,7 +3,6 @@ variable "vsphere_username" {}
variable "vsphere_password" {} variable "vsphere_password" {}
variable "vsphere_host" {} variable "vsphere_host" {}
variable "vsphere_hostip" {}
variable "vsphere_datacenter" {} variable "vsphere_datacenter" {}
variable "vsphere_templatefolder" {} variable "vsphere_templatefolder" {}
@@ -15,13 +14,5 @@ variable "vm_name" {}
variable "vm_guestos" {} variable "vm_guestos" {}
variable "winrm_password" {} variable "winrm_password" {}
variable "iso_url" {}
variable "iso_checksum" {}
variable "iso_paths" {}
variable "repo_username" {} variable "repo_username" {}
variable "repo_password" {} variable "repo_password" {}
local "iso_authenticatedurl" {
expression = "https://${var.repo_username}:${var.repo_password}@${var.iso_url}"
sensitive = true
}
-1
View File
@@ -2,7 +2,6 @@ vcenter_server = "bv11-vc.bessems.lan"
vsphere_username = "administrator@vsphere.local" vsphere_username = "administrator@vsphere.local"
vsphere_datacenter = "DeSchakel" vsphere_datacenter = "DeSchakel"
vsphere_host = "bv11-esx.bessems.lan" vsphere_host = "bv11-esx.bessems.lan"
vsphere_hostip = "192.168.11.200"
vsphere_datastore = "Datastore01.SSD" vsphere_datastore = "Datastore01.SSD"
vsphere_folder = "/Packer" vsphere_folder = "/Packer"
vsphere_templatefolder = "/Templates" vsphere_templatefolder = "/Templates"
+133
View 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"
]
}
}
-313
View File
@@ -1,313 +0,0 @@
packer {
required_plugins {
windows-update = {
version = ">= 0.12.0"
source = "github.com/rgl/windows-update"
}
}
}
source "vsphere-iso" "srv2019-template" {
vcenter_server = var.vcenter_server
username = var.vsphere_username
password = var.vsphere_password
insecure_connection = "true"
vm_name = "${var.vm_guestos}-${var.vm_name}-template"
datacenter = var.vsphere_datacenter
host = var.vsphere_host
folder = var.vsphere_folder
datastore = var.vsphere_datastore
guest_os_type = "windows9Server64Guest"
boot_order = "disk,cdrom"
boot_command = [""]
boot_wait = "5m"
communicator = "winrm"
winrm_username = "administrator"
winrm_password = var.winrm_password
winrm_timeout = "10m"
RAM = 4096
CPUs = 2
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/Server2019/Autounattend.xml",
"packer/preseed/Server2019/Sysprep_Unattend.xml",
"scripts/Set-NetworkProfile.ps1",
"scripts/Disable-WinRM.ps1",
"scripts/Enable-WinRM.ps1",
"scripts/Install-VMwareTools.cmd"
]
iso_url = local.iso_authenticatedurl
iso_checksum = var.iso_checksum
iso_paths = var.iso_paths
shutdown_command = "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml"
shutdown_timeout = "1h"
export {
images = false
output_directory = "/scratch/srv2019-template"
}
remove_cdrom = true
}
source "vsphere-iso" "srv2019-virtual" {
vcenter_server = var.vcenter_server
username = var.vsphere_username
password = var.vsphere_password
insecure_connection = "true"
vm_name = "${var.vm_guestos}-${var.vm_name}-virtual"
datacenter = var.vsphere_datacenter
host = var.vsphere_host
folder = var.vsphere_folder
datastore = var.vsphere_datastore
guest_os_type = "windows9Server64Guest"
boot_order = "disk,cdrom"
boot_command = [""]
boot_wait = "5m"
communicator = "winrm"
winrm_password = var.winrm_password
winrm_timeout = "10m"
winrm_username = "administrator"
RAM = 4096
CPUs = 2
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/Server2019/Autounattend.xml",
"packer/preseed/Server2019/Sysprep_Unattend.xml",
"scripts/Set-NetworkProfile.ps1",
"scripts/Disable-WinRM.ps1",
"scripts/Enable-WinRM.ps1",
"scripts/Install-VMwareTools.cmd"
]
iso_url = local.iso_authenticatedurl
iso_checksum = var.iso_checksum
iso_paths = var.iso_paths
shutdown_command = "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml"
shutdown_timeout = "1h"
export {
images = false
output_directory = "/scratch/srv2019-virtual"
}
remove_cdrom = true
}
source "vsphere-iso" "srv2019-baremetal" {
vcenter_server = var.vcenter_server
username = var.vsphere_username
password = var.vsphere_password
insecure_connection = "true"
vm_name = "${var.vm_guestos}-${var.vm_name}-baremetal"
datacenter = var.vsphere_datacenter
host = var.vsphere_host
folder = var.vsphere_folder
datastore = var.vsphere_datastore
guest_os_type = "windows9Server64Guest"
boot_order = "disk,cdrom"
boot_command = [""]
boot_wait = "5m"
communicator = "winrm"
winrm_username = "administrator"
winrm_password = var.winrm_password
winrm_timeout = "10m"
RAM = 4096
CPUs = 2
network_adapters {
network = var.vsphere_network
network_card = "vmxnet3"
}
storage {
disk_size = 20480
disk_thin_provisioned = true
}
disk_controller_type = ["pvscsi"]
usb_controller = ["xhci"]
floppy_files = [
"packer/preseed/Server2019/pvscsi/Autounattend.xml",
"packer/preseed/Server2019/Sysprep_Unattend.xml",
"scripts/Set-NetworkProfile.ps1",
"scripts/Disable-WinRM.ps1",
"scripts/Enable-WinRM.ps1",
"scripts/Install-VMwareTools.cmd"
]
iso_url = local.iso_authenticatedurl
iso_checksum = var.iso_checksum
iso_paths = var.iso_paths
shutdown_command = "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml"
shutdown_timeout = "1h"
export {
images = false
output_directory = "/scratch/srv2019-baremetal"
}
remove_cdrom = true
}
build {
// sources = [
// "source.vsphere-iso.srv2019-template",
// "source.vsphere-iso.srv2019-virtual",
// "source.vsphere-iso.srv2019-baremetal"
// ]
sources = [
"source.vsphere-iso.srv2019-template",
"source.vsphere-iso.srv2019-virtual"
]
provisioner "windows-update" {
}
// provisioner "powershell" {
// scripts = [
// "scripts/Install-Prerequisites.ps1",
// "scripts/Install-WinGet.ps1"
// ]
// }
// provisioner "powershell" {
// inline = [
// "winget install mozilla.firefox",
// "winget install 7zip.7zip",
// "winget install microsoft.dotnetframework"
// ]
// // valid_exit_codes = [0, 3010]
// }
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 dotnetfx",
"choco install -y 7zip.install",
"choco install -y sysinternals",
"choco install -y firefox"
]
valid_exit_codes = [0, 3010]
}
provisioner "windows-update" {
}
provisioner "powershell" {
only = ["vsphere-iso.srv2019-virtual"]
inline = [
"New-Item -Path 'C:\\Payload\\Scripts' -ItemType 'Directory' -Force:$True -Confirm:$False"
]
}
provisioner "file" {
only = ["vsphere-iso.srv2019-virtual"]
destination = "C:\\Payload\\"
source = "scripts/payload/"
}
provisioner "powershell" {
only = ["vsphere-iso.srv2019-virtual"]
scripts = [
"scripts/Register-ScheduledTask.ps1"
]
}
post-processors {
post-processor "vsphere" {
only = ["vsphere-iso.srv2019-template"]
host = var.vcenter_server
username = var.vsphere_username
password = var.vsphere_password
insecure = true
vm_name = "Windows-Server-2019-LTSC"
datacenter = var.vsphere_datacenter
cluster = var.vsphere_host
vm_folder = var.vsphere_templatefolder
vm_network = var.vsphere_network
datastore = var.vsphere_datastore
disk_mode = "thin"
keep_input_artifact = true
overwrite = true
}
post-processor "vsphere-template" {
only = ["vsphere-iso.srv2019-template"]
host = var.vcenter_server
username = var.vsphere_username
password = var.vsphere_password
insecure = true
datacenter = var.vsphere_datacenter
folder = var.vsphere_templatefolder
reregister_vm = false
}
}
post-processor "shell-local" {
only = ["vsphere-iso.srv2019-virtual"]
inline = [
"pwsh -command \"& scripts/Update-OvfConfiguration.ps1 \\",
" -OVFFile '/scratch/srv2019-virtual/${var.vm_guestos}-${var.vm_name}-virtual.ovf' \\",
" -Parameter @{'appliance.name'='${var.vm_guestos}';'appliance.version'='${var.vm_name}'}\"",
"pwsh -file scripts/Update-Manifest.ps1 \\",
" -ManifestFileName '/scratch/srv2019-virtual/${var.vm_guestos}-${var.vm_name}-virtual.mf'",
"ovftool --acceptAllEulas --allowExtraConfig --overwrite \\",
" '/scratch/srv2019-virtual/${var.vm_guestos}-${var.vm_name}-virtual.ovf' \\",
" /output/Windows-Server-2019-LTSC.ova"
]
}
post-processor "shell-local" {
only = ["vsphere-iso.srv2019-baremetal"]
inline = [
"qemu-img convert -f vmdk -O raw \\",
" /scratch/srv2019-baremetal/${var.vm_guestos}-${var.vm_name}-baremetal-disk-0.vmdk \\",
" /tmp/${var.vm_guestos}-${var.vm_name}.raw",
"gzip -c \\",
" /tmp/${var.vm_guestos}-${var.vm_name}.raw \\",
" > /output/Windows-Server-2019-LTSC.raw.gz"
]
}
}
-40
View File
@@ -1,40 +0,0 @@
[CmdletBinding()]
Param(
# No parameters
)
$RequiredPSModules = @(
'ntobjectmanager' # Provides cmdlet 'Set-ExecutionAlias'
)
$InstallPackageProviderSplat = @{
Name = 'NuGet'
MinimumVersion = '2.8.5.201'
Force = $True
Confirm = $False
}
Install-PackageProvider @InstallPackageProviderSplat
$SetPSRepositorySplat = @{
Name = 'PSGallery'
InstallationPolicy = 'Trusted'
}
Set-PSRepository @SetPSRepositorySplat
$InstallModuleSplat = @{
Name = $RequiredPSModules
Force = $True
Confirm = $False
}
Install-Module @InstallModuleSplat
$SetPSRepositorySplat = @{
Name = 'PSGallery'
InstallationPolicy = 'Untrusted'
}
Set-PSRepository @SetPSRepositorySplat
# Double check whether the required PowerShell modules are available
ForEach ($Module in $RequiredPSModules) {
If ([boolean](Get-Module -Name $Module -ListAvailable) -ne $True) {
Write-Error -Message "Missing PowerShell module '$($Module)'"
Exit 1
}
}
-74
View File
@@ -1,74 +0,0 @@
#Requires -Modules 'NtObjectManager'
[CmdletBinding()]
Param(
# None
)
# Download dependencies
$AppxDependencies = @(
@{
ShortName = 'vclibs'
QualifiedName = 'Microsoft.VCLibs.140.00_8wekyb3d8bbwe'
},
@{
ShortName = 'vclibsuwp'
QualifiedName = 'Microsoft.VCLibs.140.00.UWPDesktop_8wekyb3d8bbwe'
}
)
ForEach ($Dependency in $AppxDependencies) {
$InvokeWebRequestSplat = @{
Uri = 'https://store.rg-adguard.net/api/GetFiles'
Method = 'POST'
ContentType = 'application/x-www-form-urlencoded'
Body = "type=PackageFamilyName&url=$($Dependency.QualifiedName)&ring=RP&lang=en-US"
UseBasicParsing = $True
}
$InvokeWebRequestSplat = @{
Uri = ((Invoke-WebRequest @InvokeWebRequestSplat).Links | Where-Object {$_.OuterHTML -match '.appx' -and $_.outerHTML -match 'x64'}).href
OutFile = "$env:temp/$($Dependency.ShortName).appx"
}
Invoke-WebRequest @InvokeWebRequestSplat
}
# Download latest release (along with license) from github
$InvokeRestMethodSplat = @{
Uri = "https://api.github.com/repos/microsoft/winget-cli/releases/latest"
Method = 'GET'
}
$LatestRelease = Invoke-RestMethod @InvokeRestMethodSplat
$InvokeWebRequestSplat = @{
Uri = ($LatestRelease.assets | Where-Object {$_.name -like '*.msixbundle'}).browser_download_url
OutFile = "$env:temp\winget.msixbundle"
}
Invoke-WebRequest @InvokeWebRequestSplat
$InvokeWebRequestSplat = @{
Uri = ($LatestRelease.assets | Where-Object {$_.name -like '*license*.xml'}).browser_download_url
OutFile = "$env:temp\wingetlicense.xml"
}
Invoke-WebRequest @InvokeWebRequestSplat
# Install dependencies
$AppxDependencies.ShortName | ForEach-Object {
$AddAppxPackageSplat = @{
Path = "$env:temp/$($_).appx"
}
Add-AppxPackage @AddAppxPackageSplat
}
# Install winget
$AddAppxProvisionedPackageSplat = @{
Online = $True
PackagePath = "$env:temp\winget.msixbundle"
LicensePath = "$env:temp\wingetlicense.xml"
}
Add-AppxProvisionedPackage @AddAppxProvisionedPackageSplat
# Create reparse point
$SetExecutionAliasSplat = @{
Path = "$([System.Environment]::SystemDirectory)\winget.exe"
PackageName = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe"
EntryPoint = "Microsoft.DesktopAppInstaller_8wekyb3d8bbwe!winget"
Target = "$((Get-AppxPackage Microsoft.DesktopAppInstaller).InstallLocation)\AppInstallerCLI.exe"
AppType = 'Desktop'
Version = 3
}
Set-ExecutionAlias @SetExecutionAliasSplat
& explorer.exe "shell:appsFolder\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe!winget"
+73
View File
@@ -0,0 +1,73 @@
<?xml version="1.0" encoding="utf-8" ?>
<BlockList>
<!-- services to disable -->
<Services>
<Name>MVMCP2VAgent</Name>
<Name>VMTools</Name>
<Name> VMUpgradeHelper </Name>
<Name> vmvss </Name>
<Name>vmdesched</Name>
<Name>Virtual Server</Name>
<!-- Virtual Machine Helper -->
<Name>vmh</Name>
<!-- Xen-specific service -->
<Name>xensvc</Name>
</Services>
<!-- drivers to disable -->
<Drivers>
<Name>vmx_svga</Name>
<Name>vmmouse</Name>
<Name>vmscsi</Name>
<Name>amdpcn</Name>
<Name>PCnet</Name>
<Name>VMMEMCTL</Name>
<Name> pvscsi </Name>
<Name> vmci </Name>
<Name> vmmouse </Name>
<Name> vmaudio </Name>
<Name> vmrawdsk </Name>
<Name> vmxnet </Name>
<Name> vmxnet3ndis6 </Name>
<Name> vm3dmp </Name>
<Name> vmdebug </Name>
<Name> vmxnet3ndis5 </Name>
<Name>cirrus</Name>
<!-- storage drivers -->
<Name>buslogic</Name>
<Name>symc810</Name>
<Name>cpqarray</Name>
<Name>pcntn4m</Name>
<Name>cpqnf3</Name>
<Name>MRaidNT</Name>
<Name>Symc8XX</Name>
<!-- VIA chipset drivers -->
<Name>viaide</Name>
<Name>VIAudio</Name>
<Name>VIAPFD</Name>
<Name>viafilter</Name>
<Name>viaagp</Name>
<Name>viaagp1</Name>
<!-- network drivers: Intel(R) PRO/100 -->
<Name>E100B</Name>
<!-- tape drivers -->
<Name>4mmdat</Name>
<Name>4mmdat-SeSFT</Name>
<Name>SCSIChanger</Name>
<!-- Virtual Machine Monitor -->
<Name>vmm</Name>
<!-- Xen-specific drivers -->
<Name>xenevtchn</Name>
<Name>xenvbd</Name>
<Name>xennet</Name>
</Drivers>
<Programs>
<Name>ProMON</Name>
<Name>s3tray2</Name>
<Name>VMwareTray</Name>
<Name>VMwareUser</Name>
</Programs>
</BlockList>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+75 -134
View File
@@ -47,77 +47,7 @@ $GetContentSplat = @{
} }
$XML = [xml](Get-Content @GetContentSplat) $XML = [xml](Get-Content @GetContentSplat)
$NS = [System.Xml.XmlNamespaceManager]$XML.NameTable $NS = [System.Xml.XmlNamespaceManager]$XML.NameTable
[void]$NS.AddNamespace('ns', $XML.DocumentElement.xmlns) [void]$NS.AddNamespace('Any', $XML.DocumentElement.xmlns)
[void]$NS.AddNamespace('ovf', $XML.DocumentElement.ovf)
[void]$NS.AddNamespace('rasd', $XML.DocumentElement.rasd)
[void]$NS.AddNamespace('vmw', $XML.DocumentElement.vmw)
# Create copy of existing 'Item/ResourceType'=17 (=Hard disk) node
$XMLDiskTemplate = $XML.SelectSingleNode("//ns:VirtualHardwareSection/ns:Item/rasd:ResourceType[.='17']", $NS).ParentNode.CloneNode($True)
ForEach ($Disk in $OVFConfig.DynamicDisks) {
# Determine next free available 'diskId'
$XMLDisks = $XML.SelectNodes("//ns:DiskSection/ns:Disk[contains(@ovf:diskId,'vmdisk')]", $NS)
$DiskId = 1
While ($XMLDisks.DiskId -contains "vmdisk$($DiskId)") {
$DiskId++
}
# Add new 'Disk' node (under 'DiskSection')
$XMLDisk = $XML.CreateElement('Disk', $XML.DocumentElement.xmlns)
$PowersMap = @{
KB = 10
MB = 20
GB = 30
TB = 40
PB = 50
}
If ($PowersMap.Keys -notcontains $Disk.UnitSize) {
# Invalid UnitSize; skipping adding new disk
Continue
}
[void]$XMLDisk.SetAttribute('capacityAllocationUnits', $NS.LookupNamespace('ovf'), "byte * 2^$($PowersMap[$Disk.UnitSize])")
[void]$XMLDisk.SetAttribute('format', $NS.LookupNamespace('ovf'), 'http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized')
[void]$XMLDisk.SetAttribute('diskId', $NS.LookupNamespace('ovf'), "vmdisk$($DiskId)")
[void]$XMLDisk.SetAttribute('capacity', $NS.LookupNamespace('ovf'), '${{vmconfig.disksize.{0}}}' -f $DiskId)
[void]$XMLDisk.SetAttribute('populatedSize', $NS.LookupNamespace('ovf'), 0)
[void]$XML.SelectSingleNode('//ns:DiskSection', $NS).AppendChild($XMLDisk)
# Add new 'Item/ResourceType' node (under 'VirtualHardwareSection')
$XMLDiskItem = $XMLDiskTemplate.CloneNode($True)
$XMLDiskItem.SelectSingleNode('rasd:AddressOnParent', $NS).InnerText = ($DiskId - 1)
$XMLDiskItem.SelectSingleNode('rasd:ElementName', $NS).InnerText = "Hard Disk $($DiskId)"
$XMLDiskItem.SelectSingleNode('rasd:HostResource', $NS).InnerText = "ovf:/disk/vmdisk$($DiskId)"
# Determine next free available and highest 'InstanceID'
$InstanceIDs = $XML.SelectNodes('//ns:VirtualHardwareSection/ns:Item/rasd:InstanceID', $NS).InnerText
$InstanceID = 1
While ($InstanceIDs -contains $InstanceID) {
$InstanceID++
}
$HighestInstanceID = ($InstanceIDs | Measure-Object -Maximum).Maximum
$XMLDiskItem.SelectSingleNode('rasd:InstanceID', $NS).InnerText = $InstanceID
[void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).InsertAfter(
$XMLDiskItem,
$XML.SelectSingleNode("//ns:VirtualHardwareSection/ns:Item/rasd:InstanceID[.='$($HighestInstanceID)']", $NS).ParentNode
)
$OVFConfig.PropertyCategories[0].ProductProperties += @{
Key = "vmconfig.disksize.$($DiskId)"
Type = If ([boolean]$Disk.Constraints.Minimum -or [boolean]$Disk.Constraints.Maximum) {
"Int($($Disk.Constraints.Minimum)..$($Disk.Constraints.Maximum))"
}
Else {
'Int'
}
Label = "Disk $($DiskId) size*"
Description = "$($Disk.Description) (in $($Disk.UnitSize))".Trim()
DefaultValue = "$($Disk.Constraints.Minimum)"
Configurations = '*'
UserConfigurable = 'true'
}
}
Write-Host "Inserted $($OVFConfig.DynamicDisks.Count) new node(s) into 'DiskSection' and 'VirtualHardwareSection' respectively"
If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { If ($OVFConfig.DeploymentConfigurations.Count -gt 0) {
$XMLSection = $XML.CreateElement('DeploymentOptionSection', $XML.DocumentElement.xmlns) $XMLSection = $XML.CreateElement('DeploymentOptionSection', $XML.DocumentElement.xmlns)
@@ -128,72 +58,52 @@ If ($OVFConfig.DeploymentConfigurations.Count -gt 0) {
ForEach ($Configuration in $OVFConfig.DeploymentConfigurations) { ForEach ($Configuration in $OVFConfig.DeploymentConfigurations) {
$XMLConfig = $XML.CreateElement('Configuration', $XML.DocumentElement.xmlns) $XMLConfig = $XML.CreateElement('Configuration', $XML.DocumentElement.xmlns)
[void]$XMLConfig.SetAttribute('id', $NS.LookupNamespace('ovf'), $Configuration.Id) $XMLConfigAttrId = $XML.CreateAttribute('id', $XML.DocumentElement.ovf)
$XMLConfigAttrId.Value = $Configuration.Id
$XMLConfigLabel = $XML.CreateElement('Label', $XML.DocumentElement.xmlns) $XMLConfigLabel = $XML.CreateElement('Label', $XML.DocumentElement.xmlns)
$XMLConfigLabel.InnerText = $Configuration.Label $XMLConfigLabel.InnerText = $Configuration.Label
$XMLConfigDescription = $XML.CreateElement('Description', $XML.DocumentElement.xmlns) $XMLConfigDescription = $XML.CreateElement('Description', $XML.DocumentElement.xmlns)
$XMLConfigDescription.InnerText = $Configuration.Description $XMLConfigDescription.InnerText = $Configuration.Description
[void]$XMLConfig.Attributes.Append($XMLConfigAttrId)
[void]$XMLConfig.AppendChild($XMLConfigLabel) [void]$XMLConfig.AppendChild($XMLConfigLabel)
[void]$XMLConfig.AppendChild($XMLConfigDescription) [void]$XMLConfig.AppendChild($XMLConfigDescription)
[void]$XMLSection.AppendChild($XMLConfig) [void]$XMLSection.AppendChild($XMLConfig)
} }
[void]$XML.SelectSingleNode('//ns:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//ns:NetworkSection', $NS)) [void]$XML.SelectSingleNode('//Any:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//Any:NetworkSection', $NS))
Write-Host "Inserted 'DeploymentOptionSection' with $($Configuration.Count) nodes" Write-Host "Inserted 'DeploymentOptionSection' with $($Configuration.Count) nodes"
If ($OVFConfig.DeploymentConfigurations.Count -eq $OVFConfig.DeploymentConfigurations.Size.Count) {
# Create copies of existing 'Item/ResourceType' nodes
$XMLCPUTemplate = $XML.SelectSingleNode("//ns:VirtualHardwareSection/ns:Item/rasd:ResourceType[.='3']", $NS).ParentNode.CloneNode($True)
$XMLMemoryTemplate = $XML.SelectSingleNode("//ns:VirtualHardwareSection/ns:Item/rasd:ResourceType[.='4']", $NS).ParentNode.CloneNode($True)
# Delete existing nodes
ForEach ($Node in $XML.SelectNodes("//ns:VirtualHardwareSection/ns:Item/rasd:ResourceType[.='3' or .='4']", $NS).ParentNode) {
[void]$Node.ParentNode.RemoveChild($Node)
}
# Add adjusted 'Item/ResourceType' nodes
ForEach ($Configuration in $OVFConfig.DeploymentConfigurations) {
$XMLCPU = $XMLCPUTemplate.CloneNode($True)
[void]$XMLCPU.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $Configuration.Id)
$XMLCPU.SelectSingleNode('rasd:ElementName', $NS).InnerText = '{0} virtual CPU(s)' -f $Configuration.Size.CPU
$XMLCPU.SelectSingleNode('rasd:VirtualQuantity', $NS).InnerText = $Configuration.Size.CPU
$XMLMemory = $XMLMemoryTemplate.CloneNode($True)
[void]$XMLMemory.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $Configuration.Id)
$XMLMemory.SelectSingleNode('rasd:ElementName', $NS).InnerText = '{0}MB of memory' -f $Configuration.Size.Memory
$XMLMemory.SelectSingleNode('rasd:VirtualQuantity', $NS).InnerText = $Configuration.Size.Memory
[void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).InsertAfter(
$XMLCPU,
$XML.SelectSingleNode('//ns:VirtualHardwareSection/ns:System', $NS)
)
[void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).InsertAfter(
$XMLMemory,
$XML.SelectSingleNode('//ns:VirtualHardwareSection/ns:System', $NS)
)
}
}
} }
[void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).SetAttribute('transport', $NS.LookupNamespace('ovf'), 'com.vmware.guestInfo') $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) { ForEach ($ExtraConfig in $OVFConfig.AdvancedOptions) {
$XMLExtraConfig = $XML.CreateElement('vmw:ExtraConfig', $XML.DocumentElement.vmw) $XMLExtraConfig = $XML.CreateElement('vmw:ExtraConfig', $XML.DocumentElement.vmw)
[void]$XMLExtraConfig.SetAttribute('required', $NS.LookupNamespace('ovf'), "$([boolean]$ExtraConfig.Required)".ToLower()) $XMLExtraConfigAttrRequired = $XML.CreateAttribute('required', $XML.DocumentElement.ovf)
[void]$XMLExtraConfig.SetAttribute('key', $NS.LookupNamespace('vmw'), $ExtraConfig.Key) $XMLExtraConfigAttrRequired.Value = "$([boolean]$ExtraConfig.Required)".ToLower()
[void]$XMLExtraConfig.SetAttribute('value', $NS.LookupNamespace('vmw'), $ExtraConfig.Value) $XMLExtraConfigAttrKey = $XML.CreateAttribute('key', $XML.DocumentElement.vmw)
$XMLExtraConfigAttrKey.Value = $ExtraConfig.Key
$XMLExtraConfigAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.vmw)
$XMLExtraConfigAttrValue.Value = $ExtraConfig.Value
[void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).AppendChild($XMLExtraConfig) [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' node(s)" Write-Host "Added $($OVFConfig.AdvancedOptions.Count) 'vmw:ExtraConfig' nodes"
$XMLProductSection = $XML.SelectSingleNode('//ns:ProductSection', $NS) $XMLProductSection = $XML.SelectSingleNode('//Any:ProductSection', $NS)
If ($XMLProductSection -eq $Null) { If ($XMLProductSection -eq $Null) {
$XMLProductSection = $XML.CreateElement('ProductSection', $XML.DocumentElement.xmlns) $XMLProductSection = $XML.CreateElement('ProductSection', $XML.DocumentElement.xmlns)
[void]$XML.SelectSingleNode('//ns:VirtualSystem', $NS).AppendChild($XMLProductSection) [void]$XML.SelectSingleNode('//Any:VirtualSystem', $NS).AppendChild($XMLProductSection)
Write-Host "Inserted 'ProductSection'" Write-Host "Inserted 'ProductSection'"
} Else { } Else {
ForEach ($Child in $XMLProductSection.SelectNodes('//ns:ProductSection/child::*', $NS)) { ForEach ($Child in $XMLProductSection.SelectNodes('//Any:ProductSection/child::*', $NS)) {
[void]$Child.ParentNode.RemoveChild($Child) [void]$Child.ParentNode.RemoveChild($Child)
} }
Write-Host "Destroyed pre-existing children in 'ProductSection'" Write-Host "Destroyed pre-existing children in 'ProductSection'"
@@ -214,13 +124,15 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
ForEach ($Property in $Category.ProductProperties) { ForEach ($Property in $Category.ProductProperties) {
$XMLProperty = $XML.CreateElement('Property', $XML.DocumentElement.xmlns) $XMLProperty = $XML.CreateElement('Property', $XML.DocumentElement.xmlns)
[void]$XMLProperty.SetAttribute('key', $NS.LookupNamespace('ovf'), $Property.Key) $XMLPropertyAttrKey = $XML.CreateAttribute('key', $XML.DocumentElement.ovf)
$XMLPropertyAttrKey.Value = $Property.Key
$XMLPropertyAttrType = $XML.CreateAttribute('type', $XML.DocumentElement.ovf)
Switch -regex ($Property.Type) { Switch -regex ($Property.Type) {
'^boolean' { '^boolean' {
[void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'boolean') $XMLPropertyAttrType.Value = 'boolean'
} }
'^int' { '^int' {
[void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'uint16') $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]) {
@@ -229,16 +141,23 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
If ($Matches[2]) { If ($Matches[2]) {
$Qualifiers += "MaxValue($($Matches[2]))" $Qualifiers += "MaxValue($($Matches[2]))"
} }
[void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), $Qualifiers -join ' ') $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf)
$XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
} }
'^ip' { '^ip' {
[void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'string') $XMLPropertyAttrType.Value = 'string'
[void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('vmw'), 'Ip') $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.vmw)
$XMLPropertyAttrQualifiers.Value = 'Ip'
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
'^password' { '^password' {
[void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'string') $XMLPropertyAttrType.Value = 'string'
[void]$XMLProperty.SetAttribute('password', $NS.LookupNamespace('ovf'), 'true') $XMLPropertyAttrPassword = $XML.CreateAttribute('password', $XML.DocumentElement.ovf)
$XMLPropertyAttrPassword.Value = 'true'
[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]) {
@@ -247,11 +166,13 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
If ($Matches[2]) { If ($Matches[2]) {
$Qualifiers += "MaxLen($($Matches[2]))" $Qualifiers += "MaxLen($($Matches[2]))"
} }
[void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), $Qualifiers -join ' ') $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf)
$XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
} }
'^string' { '^string' {
[void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), '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]) {
@@ -260,19 +181,28 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
If ($Matches[2]) { If ($Matches[2]) {
$Qualifiers += "MaxLen($($Matches[2]))" $Qualifiers += "MaxLen($($Matches[2]))"
} }
[void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), $Qualifiers -join ' ') $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\[(.*)\]') {
[void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), "ValueMap{$($Matches[1] -replace '","', '", "')}") $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf)
$XMLPropertyAttrQualifiers.Value = "ValueMap{$($Matches[1] -replace '","', '", "')}"
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
} }
} }
[void]$XMLProperty.SetAttribute('userConfigurable', $NS.LookupNamespace('ovf'), "$([boolean]$Property.UserConfigurable)".ToLower()) $XMLPropertyAttrUserConfigurable = $XML.CreateAttribute('userConfigurable', $XML.DocumentElement.ovf)
$XMLPropertyAttrUserConfigurable.Value = "$([boolean]$Property.UserConfigurable)".ToLower()
$XMLPropertyAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf)
If ($Property.Type -eq 'boolean') { If ($Property.Type -eq 'boolean') {
[void]$XMLProperty.SetAttribute('value', $NS.LookupNamespace('ovf'), "$([boolean]$Property.DefaultValue)".ToLower()) $XMLPropertyAttrValue.Value = "$([boolean]$Property.DefaultValue)".ToLower()
} Else { } Else {
[void]$XMLProperty.SetAttribute('value', $NS.LookupNamespace('ovf'), $Property.DefaultValue) $XMLPropertyAttrValue.Value = $Property.DefaultValue
} }
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrKey)
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrType)
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrUserConfigurable)
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrValue)
If ($Property.Label) { If ($Property.Label) {
$XMLPropertyLabel = $XML.CreateElement('Label', $XML.DocumentElement.xmlns) $XMLPropertyLabel = $XML.CreateElement('Label', $XML.DocumentElement.xmlns)
@@ -286,19 +216,30 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
} }
If (($Property.Configurations.Count -eq 1) -and ($Property.Configurations -eq '*')) { If (($Property.Configurations.Count -eq 1) -and ($Property.Configurations -eq '*')) {
[void]$XMLProperty.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $OVFConfig.DeploymentConfigurations.Id -join ' ') $XMLPropertyAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf)
$XMLPropertyAttrConfiguration.Value = $OVFConfig.DeploymentConfigurations.Id -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrConfiguration)
} ElseIf ($Property.Configurations.Count -gt 0) { } ElseIf ($Property.Configurations.Count -gt 0) {
[void]$XMLProperty.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $Property.Configurations -join ' ') $XMLPropertyAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf)
$XMLPropertyAttrConfiguration.Value = $Property.Configurations -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrConfiguration)
} }
If ($Property.Value.Count -eq 1) { If ($Property.Value.Count -eq 1) {
[void]$XMLProperty.SetAttribute('value', $NS.LookupNamespace('ovf'), $Property.Value) $XMLPropertyAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf)
$XMLPropertyAttrValue.Value = $Property.Value
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrValue)
} ElseIf ($Property.Value.Count -gt 1) { } ElseIf ($Property.Value.Count -gt 1) {
ForEach ($Value in $Property.Value) { ForEach ($Value in $Property.Value) {
$XMLValue = $XML.CreateElement('Value', $XML.DocumentElement.xmlns) $XMLValue = $XML.CreateElement('Value', $XML.DocumentElement.xmlns)
[void]$XMLValue.SetAttribute('value', $NS.LookupNamespace('ovf'), $Value) $XMLValueAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf)
[void]$XMLValue.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $Value) $XMLValueAttrValue.Value = $Value
$XMLValueAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf)
$XMLValueAttrConfiguration.Value = $Value
[void]$XMLValue.Attributes.Append($XMLValueAttrValue)
[void]$XMLValue.Attributes.Append($XMLValueAttrConfiguration)
[void]$XMLProperty.AppendChild($XMLValue) [void]$XMLProperty.AppendChild($XMLValue)
} }
+13 -68
View File
@@ -1,63 +1,18 @@
DeploymentConfigurations: DeploymentConfigurations:
- Id: domainmember-small - Id: domainmember
Label: 'Domain member [SMALL: 1 vCPU/2GB RAM]' Label: Domain member
Description: Windows Server joined to an Active Directory domain. Description: Windows 10 client joined to an Active Directory domain
Size: - Id: standalone
CPU: 1 Label: Stand-alone
Memory: 2048 Description: Stand-alone Windows 10 client
- Id: domainmember-medium
Label: 'Domain member [MEDIUM: 2 vCPU/4GB RAM]'
Description: Windows Server joined to an Active Directory domain.
Size:
CPU: 2
Memory: 4096
- Id: domainmember-large
Label: 'Domain member [LARGE: 4 vCPU/8GB RAM]'
Description: Windows Server joined to an Active Directory domain.
Size:
CPU: 4
Memory: 8192
- Id: standalone-small
Label: 'Stand-alone [SMALL: 1 vCPU/2GB RAM]'
Description: Stand-alone Windows Server.
Size:
CPU: 1
Memory: 2048
- Id: standalone-medium
Label: 'Stand-alone [MEDIUM: 2 vCPU/4GB RAM]'
Description: Stand-alone Windows Server.
Size:
CPU: 2
Memory: 4096
- Id: standalone-large
Label: 'Stand-alone [LARGE: 4 vCPU/8GB RAM]'
Description: Stand-alone Windows Server.
Size:
CPU: 4
Memory: 8192
DynamicDisks:
- Description: Data
UnitSize: GB
Constraints:
Minimum: 10
Maximum: 500
- Description: Scratch
UnitSize: GB
Constraints:
Minimum: 5
Maximum: ''
PropertyCategories: PropertyCategories:
- Name: 0) Deployment information - Name: 0) Deployment information
ProductProperties: ProductProperties:
- Key: deployment.type - Key: deployment.type
Type: string Type: string
Value: Value:
- domainmember-small - domainmember
- domainmember-medium - standalone
- domainmember-large
- standalone-small
- standalone-medium
- standalone-large
UserConfigurable: false UserConfigurable: false
- Name: 1) Operating System - Name: 1) Operating System
ProductProperties: ProductProperties:
@@ -74,9 +29,7 @@ PropertyCategories:
Description: Must meet password complexity rules Description: Must meet password complexity rules
DefaultValue: password DefaultValue: password
Configurations: Configurations:
- standalone-small - standalone
- standalone-medium
- standalone-large
UserConfigurable: true UserConfigurable: true
- Key: guestinfo.ntpserver - Key: guestinfo.ntpserver
Type: string(1..) Type: string(1..)
@@ -84,9 +37,7 @@ PropertyCategories:
Description: A comma-separated list of timeservers Description: A comma-separated list of timeservers
DefaultValue: 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org DefaultValue: 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org
Configurations: Configurations:
- standalone-small - standalone
- standalone-medium
- standalone-large
UserConfigurable: true UserConfigurable: true
- Name: 2) Networking - Name: 2) Networking
ProductProperties: ProductProperties:
@@ -126,9 +77,7 @@ PropertyCategories:
Description: Must be able to be resolved through provided DNS server Description: Must be able to be resolved through provided DNS server
DefaultValue: example.org DefaultValue: example.org
Configurations: Configurations:
- domainmember-small - domainmember
- domainmember-medium
- domainmember-large
UserConfigurable: true UserConfigurable: true
- Key: addsconfig.username - Key: addsconfig.username
Type: string(1..) Type: string(1..)
@@ -136,9 +85,7 @@ PropertyCategories:
Description: '' Description: ''
DefaultValue: username DefaultValue: username
Configurations: Configurations:
- domainmember-small - domainmember
- domainmember-medium
- domainmember-large
UserConfigurable: true UserConfigurable: true
- Key: addsconfig.password - Key: addsconfig.password
Type: password(1..) Type: password(1..)
@@ -146,9 +93,7 @@ PropertyCategories:
Description: '' Description: ''
DefaultValue: password DefaultValue: password
Configurations: Configurations:
- domainmember-small - domainmember
- domainmember-medium
- domainmember-large
UserConfigurable: true UserConfigurable: true
AdvancedOptions: AdvancedOptions:
- Key: appliance.name - Key: appliance.name
@@ -34,11 +34,11 @@ foreach ($ovfProperty in $ovfProperties) {
} }
# Check for mandatory values # Check for mandatory values
Switch -regex ($ovfPropertyValues['deployment.type']) { Switch ($ovfPropertyValues['deployment.type']) {
'^domainmember' { 'domainmember' {
$MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.gateway', 'addsconfig.domainname', 'addsconfig.username', 'addsconfig.password'), @() $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.gateway', 'addsconfig.domainname', 'addsconfig.username', 'addsconfig.password'), @()
} }
'^standalone' { 'standalone' {
$MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.gateway', 'guestinfo.administratorpw', 'guestinfo.ntpserver'), @() $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.gateway', 'guestinfo.administratorpw', 'guestinfo.ntpserver'), @()
} }
default { default {
@@ -152,8 +152,8 @@ If ((Get-WmiObject -Class 'Win32_NetworkAdapterConfiguration').IPAddress -NotCon
$ErrorActionPreference, $OldErrorActionPreference = $OldErrorActionPreference, $NULL $ErrorActionPreference, $OldErrorActionPreference = $OldErrorActionPreference, $NULL
} }
Switch -regex ($ovfPropertyValues['deployment.type']) { Switch ($ovfPropertyValues['deployment.type']) {
'^domainmember' { 'domainmember' {
# Join Active Directory domain as member # Join Active Directory domain as member
If (!(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) { If (!(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) {
$AddComputerSplat = @{ $AddComputerSplat = @{
@@ -174,7 +174,7 @@ Switch -regex ($ovfPropertyValues['deployment.type']) {
# Exit # Exit
} }
} }
'^standalone' { 'standalone' {
# Change password of built-in Administrator # Change password of built-in Administrator
$BuiltinAdministrator = (Get-LocalUser | Where-Object {$_.SID -match '-500'}) $BuiltinAdministrator = (Get-LocalUser | Where-Object {$_.SID -match '-500'})
$ConvertToSecureStringSplat = @{ $ConvertToSecureStringSplat = @{
@@ -192,6 +192,12 @@ Switch -regex ($ovfPropertyValues['deployment.type']) {
Confirm = $False Confirm = $False
} }
Set-LocalUser @SetLocalUserSplat Set-LocalUser @SetLocalUserSplat
$EnableLocalUserSplat = @{
InputObject = $BuiltinAdministrator
Confirm = $False
}
Enable-LocalUser @EnableLocalUserSplat
} }
} }