Add two DeploymentOptions w/ distinct vApp props
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
c1eeaa9f7f
commit
fed9292100
7
scripts/Server2019/Register-ScheduledTask.ps1
Normal file
7
scripts/Server2019/Register-ScheduledTask.ps1
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
# No parameters
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create scheduled task
|
||||||
|
& schtasks.exe /Create /TN 'OVF-Properties' /SC ONSTART /RU SYSTEM /TR "powershell.exe -file C:\Payload\Apply-OVFProperties.ps1"
|
230
scripts/Server2019/payload/Apply-OVFProperties.ps1
Normal file
230
scripts/Server2019/payload/Apply-OVFProperties.ps1
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
#Requires -Modules 'ADDSDeployment'
|
||||||
|
[CmdletBinding()]
|
||||||
|
Param(
|
||||||
|
# No parameters
|
||||||
|
)
|
||||||
|
|
||||||
|
$NewEventLogSplat = @{
|
||||||
|
LogName = 'Application'
|
||||||
|
Source = 'OVF-Properties'
|
||||||
|
ErrorAction = 'SilentlyContinue'
|
||||||
|
}
|
||||||
|
New-EventLog @NewEventLogSplat
|
||||||
|
$WriteEventLogSplat = @{
|
||||||
|
LogName = 'Application'
|
||||||
|
Source = 'OVF-Properties'
|
||||||
|
EntryType = 'Information'
|
||||||
|
EventID = 1
|
||||||
|
Message = 'OVF-Properties sequence initiated'
|
||||||
|
}
|
||||||
|
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 = 'OVF-Properties'
|
||||||
|
EntryType = 'Error'
|
||||||
|
EventID = 66
|
||||||
|
Message = "Unexpected or no value set for property 'deployment.type', cannot provision."
|
||||||
|
}
|
||||||
|
Write-EventLog @WriteEventLogSplat
|
||||||
|
& schtasks.exe /Change /TN 'OVF-Properties' /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 = 'OVF-Properties'
|
||||||
|
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 'OVF-Properties' /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']
|
||||||
|
}
|
||||||
|
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 = 'OVF-Properties'
|
||||||
|
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 = @{
|
||||||
|
InterfaceAlias = (Get-NetAdapter).Name
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
}
|
||||||
|
Get-Item @GetItemSplat | ForEach-Object {
|
||||||
|
Try {
|
||||||
|
$WriteEventLogSplat = @{
|
||||||
|
LogName = 'Application'
|
||||||
|
Source = 'OVF-Properties'
|
||||||
|
EntryType = 'Information'
|
||||||
|
EventID = 4
|
||||||
|
Message = "Running script: '$($_.FullName)'"
|
||||||
|
}
|
||||||
|
Write-EventLog @WriteEventLogSplat
|
||||||
|
& $_.FullName -Parameter $ovfPropertyValues
|
||||||
|
}
|
||||||
|
Catch {
|
||||||
|
$WriteEventLogSplat = @{
|
||||||
|
LogName = 'Application'
|
||||||
|
Source = 'OVF-Properties'
|
||||||
|
EntryType = 'Error'
|
||||||
|
EventID = 66
|
||||||
|
Message = $_.Exception.Message
|
||||||
|
}
|
||||||
|
Write-EventLog @WriteEventLogSplat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$WriteEventLogSplat = @{
|
||||||
|
LogName = 'Application'
|
||||||
|
Source = 'OVF-Properties'
|
||||||
|
EntryType = 'Information'
|
||||||
|
EventID = 42
|
||||||
|
Message = 'OVF-Properties sequence applied and finished'
|
||||||
|
}
|
||||||
|
Write-EventLog @WriteEventLogSplat
|
||||||
|
& schtasks.exe /Change /TN 'OVF-Properties' /DISABLE
|
@ -1,5 +1,19 @@
|
|||||||
DeploymentConfigurations: []
|
DeploymentConfigurations:
|
||||||
|
- Id: domainmember
|
||||||
|
Label: Domain member
|
||||||
|
Description: Windows Server joined to an Active Directory domain
|
||||||
|
- Id: standalone
|
||||||
|
Label: Stand-alone
|
||||||
|
Description: Stand-alone Windows Server
|
||||||
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,24 +46,54 @@ 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
|
||||||
|
- 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
|
UserConfigurable: true
|
||||||
AdvancedOptions:
|
AdvancedOptions:
|
||||||
- Key: appliance.name
|
- Key: appliance.name
|
||||||
|
Loading…
Reference in New Issue
Block a user