diff --git a/scripts/Server2019/payload/Apply-FirstBootConfig.ps1 b/scripts/Server2019/payload/Apply-FirstBootConfig.ps1 index a997806..9435fd9 100644 --- a/scripts/Server2019/payload/Apply-FirstBootConfig.ps1 +++ b/scripts/Server2019/payload/Apply-FirstBootConfig.ps1 @@ -34,11 +34,11 @@ foreach ($ovfProperty in $ovfProperties) { } # Check for mandatory values -Switch ($ovfPropertyValues['deployment.type']) { - 'domainmember' { +Switch -regex ($ovfPropertyValues['deployment.type']) { + '^domainmember' { $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'), @() } default { @@ -152,8 +152,8 @@ If ((Get-WmiObject -Class 'Win32_NetworkAdapterConfiguration').IPAddress -NotCon $ErrorActionPreference, $OldErrorActionPreference = $OldErrorActionPreference, $NULL } -Switch ($ovfPropertyValues['deployment.type']) { - 'domainmember' { +Switch -regex ($ovfPropertyValues['deployment.type']) { + '^domainmember' { # Join Active Directory domain as member If (!(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain) { $AddComputerSplat = @{ @@ -174,7 +174,7 @@ Switch ($ovfPropertyValues['deployment.type']) { # Exit } } - 'standalone' { + '^standalone' { # Change password of built-in Administrator $BuiltinAdministrator = (Get-LocalUser | Where-Object {$_.SID -match '-500'}) $ConvertToSecureStringSplat = @{ diff --git a/scripts/Update-OvfConfiguration.ps1 b/scripts/Update-OvfConfiguration.ps1 index 76deff5..499a003 100644 --- a/scripts/Update-OvfConfiguration.ps1 +++ b/scripts/Update-OvfConfiguration.ps1 @@ -176,6 +176,31 @@ If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { } [void]$XML.SelectSingleNode('//ns:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//ns:NetworkSection', $NS)) Write-Host "Inserted 'DeploymentOptionSection' with $($Configuration.Count) nodes" + + If ($OVFConfig.DeploymentConfigurations.Count -eq $OVFConfig.DeploymentConfigurations.Size.Count) { + # Create copies of default 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 default resourceType nodes + ForEach ($Node in $XML.SelectNodes("//ns:VirtualHardwareSection/ns:Item/rasd:ResourceType[.='3' or .='4']", $NS).ParentNode) { + $Node.ParentNode.RemoveChild($Node) + } + # Add updated resourceType nodes + ForEach ($Configuration in $OVFConfig.DeploymentConfigurations) { + $XMLCPU = $XMLCPUTemplate.CloneNode($True) + [void]$XMLCPU.SetAttribute('ovf:configuration', $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('ovf:configuration', $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 + + $XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).AppendChild($XMLCPU) + $XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).AppendChild($XMLMemory) + } + } } $XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) diff --git a/scripts/Update-OvfConfiguration.yml b/scripts/Update-OvfConfiguration.yml index 5e8aa5d..120dc65 100644 --- a/scripts/Update-OvfConfiguration.yml +++ b/scripts/Update-OvfConfiguration.yml @@ -1,10 +1,28 @@ DeploymentConfigurations: -- Id: domainmember +- Id: domainmember-medium Label: Domain member Description: Windows Server joined to an Active Directory domain -- Id: standalone + Size: + CPU: 2 + Memory: 4096 +- Id: domainmember-large + Label: Domain member + Description: Windows Server joined to an Active Directory domain [LARGE] + Size: + CPU: 4 + Memory: 8192 +- Id: standalone-medium Label: Stand-alone Description: Stand-alone Windows Server + Size: + CPU: 2 + Memory: 4096 +- Id: standalone-large + Label: Stand-alone + Description: Stand-alone Windows Server [LARGE] + Size: + CPU: 4 + Memory: 8192 Disks: Referenced: - Id: vmdisk1 @@ -27,8 +45,10 @@ PropertyCategories: - Key: deployment.type Type: string Value: - - domainmember - - standalone + - domainmember-medium + - domainmember-large + - standalone-medium + - standalone-large UserConfigurable: false - Name: 1) Operating System ProductProperties: @@ -45,7 +65,8 @@ PropertyCategories: Description: Must meet password complexity rules DefaultValue: password Configurations: - - standalone + - standalone-medium + - standalone-large UserConfigurable: true - Key: guestinfo.ntpserver Type: string(1..) @@ -53,7 +74,8 @@ PropertyCategories: Description: A comma-separated list of timeservers DefaultValue: 0.pool.ntp.org,1.pool.ntp.org,2.pool.ntp.org Configurations: - - standalone + - standalone-medium + - standalone-large UserConfigurable: true - Name: 2) Networking ProductProperties: @@ -93,7 +115,8 @@ PropertyCategories: Description: Must be able to be resolved through provided DNS server DefaultValue: example.org Configurations: - - domainmember + - domainmember-medium + - domainmember-large UserConfigurable: true - Key: addsconfig.username Type: string(1..) @@ -101,7 +124,8 @@ PropertyCategories: Description: '' DefaultValue: username Configurations: - - domainmember + - domainmember-medium + - domainmember-large UserConfigurable: true - Key: addsconfig.password Type: password(1..) @@ -109,7 +133,8 @@ PropertyCategories: Description: '' DefaultValue: password Configurations: - - domainmember + - domainmember-medium + - domainmember-large UserConfigurable: true AdvancedOptions: - Key: appliance.name