From aee33cca51e3a3cb7cb098e38d61679fde0a5f2d Mon Sep 17 00:00:00 2001 From: djpbessems Date: Thu, 8 Apr 2021 17:03:19 +0200 Subject: [PATCH] Safeguarding WIP --- ...operties.ps1 => Apply-FirstBootConfig.ps1} | 86 ++++++++++++++++--- scripts/Update-OvfConfiguration.yml | 19 +++- 2 files changed, 91 insertions(+), 14 deletions(-) rename scripts/ADCS/payload/{Apply-OVFProperties.ps1 => Apply-FirstBootConfig.ps1} (60%) diff --git a/scripts/ADCS/payload/Apply-OVFProperties.ps1 b/scripts/ADCS/payload/Apply-FirstBootConfig.ps1 similarity index 60% rename from scripts/ADCS/payload/Apply-OVFProperties.ps1 rename to scripts/ADCS/payload/Apply-FirstBootConfig.ps1 index 1347db7..f880621 100644 --- a/scripts/ADCS/payload/Apply-OVFProperties.ps1 +++ b/scripts/ADCS/payload/Apply-FirstBootConfig.ps1 @@ -30,21 +30,47 @@ foreach ($ovfProperty in $ovfProperties) { } # Check for mandatory values -If (!($ovfPropertyValues['guestinfo.hostname'] -and - $ovfPropertyValues['guestinfo.ipaddress'] -and - $ovfPropertyValues['guestinfo.dnsserver'] -and - $ovfPropertyValues['guestinfo.prefixlength'] -and - $ovfPropertyValues['guestinfo.gateway'])) { +Switch ($ovfPropertyValues['deployment.type']) { + 'standalone-root' { + $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.dnsserver', 'guestinfo.gateway', 'guestinfo.administratorpw', 'adcsconfig.organizationname', 'adcsconfig.foo'), @() + } + 'enterprise-intermediate' { + $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.dnsserver', 'guestinfo.gateway', 'guestinfo.administratorpw', 'adcsconfig.foo'), @() + } + 'standalone-intermediate' { + $MandatoryProperties, $MissingProperties = @('guestinfo.hostname', 'guestinfo.ipaddress', 'guestinfo.prefixlength', 'guestinfo.dnsserver', 'guestinfo.gateway', 'guestinfo.administratorpw', 'adcsconfig.foo'), @() + } + default { # Mandatory values missing, cannot provision. $WriteEventLogSplat = @{ LogName = 'Application' - Source = 'OVF-Properties' + Source = 'FirstBoot' EntryType = 'Error' EventID = 66 - Message = 'Mandatory values missing, cannot provision.' + Message = "Unexpected or no value set for property 'deployment.type', cannot provision." } Write-EventLog @WriteEventLogSplat - & schtasks.exe /Change /TN 'OVF-Properties' /DISABLE + & 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 } @@ -125,24 +151,55 @@ If ((Get-WmiObject -Class 'Win32_NetworkAdapterConfiguration').IPAddress -NotCon $ErrorActionPreference, $OldErrorActionPreference = $OldErrorActionPreference, $NULL } -# Foo +# Install and configure certificate authority +If ((& certutil.exe | Select-String "Server:") -notmatch "$Env:ComputerName") { + # 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 + + Switch ($ovfPropertyValues['deployment.type']) { + 'standalone-root' { + $InstallADCSCertificationAuthoritySplat = @{ + CACommonName = "$($ovfPropertyValues['deployment.organizationname']) Root CA" + CAType = 'StandaloneRootCA' + } + Install-ADCSCertificationAuthority @InstallADCSCertificationAuthoritySplat + } + # Foo + # Bar + } +} # 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 { +ForEach ($Script in (Get-Item @GetItemSplat)) { Try { $WriteEventLogSplat = @{ LogName = 'Application' Source = 'OVF-Properties' EntryType = 'Information' EventID = 4 - Message = "Running script: '$($_.FullName)'" + Message = "Running script: '$($Script.FullName)'" } Write-EventLog @WriteEventLogSplat - & $_.FullName -Parameter $ovfPropertyValues + & $Script.FullName -Parameter $ovfPropertyValues } Catch { $WriteEventLogSplat = @{ @@ -150,7 +207,10 @@ Get-Item @GetItemSplat | ForEach-Object { Source = 'OVF-Properties' EntryType = 'Error' EventID = 66 - Message = $_.Exception.Message + Message = @" +Error occurred while executing script '$($Script.Name)': +$($_.Exception.Message) +"@ } Write-EventLog @WriteEventLogSplat } diff --git a/scripts/Update-OvfConfiguration.yml b/scripts/Update-OvfConfiguration.yml index 71a7b1b..917d63d 100644 --- a/scripts/Update-OvfConfiguration.yml +++ b/scripts/Update-OvfConfiguration.yml @@ -27,7 +27,24 @@ PropertyCategories: DefaultValue: '' Configurations: '*' UserConfigurable: true -- Name: 2) Networking + - Key: guestinfo.administratorpw + Type: password(7..) + Label: Local administrator password* + Description: Must meet password complexity rules + DefaultValue: password + Configurations: + - standalone-root + - standalone-intermediate + 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-root + - standalone-intermediate + UserConfigurable: true- Name: 2) Networking ProductProperties: - Key: guestinfo.ipaddress Type: ip