Delete commit history (containing proprietary code)
	
		
			
	
		
	
	
		
	
		
			Some checks reported errors
		
		
	
	
		
			
				
	
				continuous-integration/drone/push Build was killed
				
			
		
		
	
	
				
					
				
			
		
			Some checks reported errors
		
		
	
	continuous-integration/drone/push Build was killed
				
			This commit is contained in:
		
							
								
								
									
										37
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								.drone.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| kind: pipeline | ||||
| type: kubernetes | ||||
| name: 'Packer Build' | ||||
|  | ||||
| steps: | ||||
| - name: Active Directory Certificate Services | ||||
|   image: bv11-cr01.bessems.eu/library/packer-extended | ||||
|   commands: | ||||
|   - | | ||||
|     packer validate \ | ||||
|       -var-file=packer/variables.vsphere.json \ | ||||
|       -var vm_name=${DRONE_COMMIT_SHA:0:10}-$DRONE_BUILD_NUMBER \ | ||||
|       -var vsphere_password=$${VSPHERE_PASSWORD} \ | ||||
|       -var winrm_password=$${WINRM_PASSWORD} \ | ||||
|       packer/adcs.json | ||||
|   - | | ||||
|     packer build \ | ||||
|       -on-error=cleanup \ | ||||
|       -var-file=packer/variables.vsphere.json \ | ||||
|       -var vm_name=${DRONE_COMMIT_SHA:0:10}-$DRONE_BUILD_NUMBER \ | ||||
|       -var vsphere_password=$${VSPHERE_PASSWORD} \ | ||||
|       -var winrm_password=$${WINRM_PASSWORD} \ | ||||
|       packer/adcs.json | ||||
|   environment: | ||||
|     VSPHERE_PASSWORD: | ||||
|       from_secret: vsphere_password | ||||
|     WINRM_PASSWORD: | ||||
|       from_secret: winrm_password | ||||
|     # PACKER_LOG: 1 | ||||
|   volumes: | ||||
|   - name: output | ||||
|     path: /output     | ||||
|  | ||||
| volumes: | ||||
| - name: output | ||||
|   claim: | ||||
|     name: flexvolsmb-drone-output | ||||
							
								
								
									
										2
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| # Packer.Images [](https://ci.spamasaurus.com/djpbessems/Packer.Images) | ||||
|  | ||||
							
								
								
									
										90
									
								
								packer/adcs.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								packer/adcs.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | ||||
| { | ||||
|     "builders": [ | ||||
|       { | ||||
|         "type":                 "vsphere-clone", | ||||
|         "name":                 "adcs", | ||||
|  | ||||
|         "vcenter_server":       "{{user `vcenter_server`}}", | ||||
|         "username":             "{{user `vsphere_username`}}", | ||||
|         "password":             "{{user `vsphere_password`}}", | ||||
|         "insecure_connection":  "true", | ||||
|  | ||||
|         "vm_name":              "adcs-{{user `vm_name`}}", | ||||
|         "datastore":            "{{user `vsphere_datastore`}}", | ||||
|         "folder":               "{{user `vsphere_folder`}}", | ||||
|         "datacenter":           "{{user `vsphere_datacenter`}}", | ||||
|         "host":                 "{{user `vsphere_host`}}", | ||||
|         "boot_order":           "disk,cdrom", | ||||
|  | ||||
|         "communicator":         "winrm", | ||||
|         "winrm_username":       "administrator", | ||||
|         "winrm_password":       "{{user `winrm_password`}}", | ||||
|         "winrm_timeout":        "10m", | ||||
|  | ||||
|         "cpus":                 2, | ||||
|         "RAM":                  8192, | ||||
|  | ||||
|         "template":             "Windows-Server-2019-LTSC", | ||||
|  | ||||
|         "floppy_files": [ | ||||
|           "packer/preseed/ADCS/Sysprep_Unattend.xml" | ||||
|         ], | ||||
|  | ||||
|         "boot_command":         "", | ||||
|         "boot_wait":            "2m30s", | ||||
|  | ||||
|         "shutdown_command":     "C:\\Windows\\System32\\Sysprep\\sysprep.exe /generalize /oobe /unattend:A:\\Sysprep_Unattend.xml", | ||||
|         "shutdown_timeout":     "1h", | ||||
|  | ||||
|         "export": { | ||||
|           "images":             false | ||||
|         } | ||||
|       } | ||||
|     ], | ||||
|     "provisioners": [ | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "inline": [ | ||||
|           "New-Item -Path 'C:\\Payload\\Scripts' -ItemType 'Directory' -Force:$True -Confirm:$False" | ||||
|         ] | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "file", | ||||
|         "source":               "scripts/ADCS/payload/", | ||||
|         "destination":          "C:\\Payload\\" | ||||
|       }, | ||||
|       { | ||||
|         "type":                 "powershell", | ||||
|         "scripts": [ | ||||
|           "scripts/ADCS/Install-Prerequisites.ps1", | ||||
|           "scripts/ADCS/Register-ScheduledTask.ps1" | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     "post-processors": [[ | ||||
|       { | ||||
|         "type":                 "shell-local", | ||||
|         "inline": [ | ||||
|           "pwsh -file scripts/Update-OvfConfiguration.ps1 \\", | ||||
|           " -OVFFile './output-adcs/adcs-{{user `vm_name`}}.ovf'", | ||||
|           "pwsh -file scripts/Update-Manifest.ps1 \\", | ||||
|           " -ManifestFileName './output-adcs/adcs-{{user `vm_name`}}.mf'", | ||||
|           "ovftool --acceptAllEulas --allowExtraConfig --overwrite \\", | ||||
|           " './output-adcs/adcs-{{user `vm_name`}}.ovf' \\", | ||||
|           " /output/ADCS-appliance.ova" | ||||
|         ] | ||||
|       } | ||||
|     ], | ||||
|     [ | ||||
|       { | ||||
|         "type":                 "shell-local", | ||||
|         "inline": [ | ||||
|           "pwsh -file scripts/Remove-Resources.ps1 \\", | ||||
|           " -VMName 'adcs-{{user `vm_name`}}' \\", | ||||
|           " -VSphereFQDN '{{user `vcenter_server`}}' \\", | ||||
|           " -VSphereUsername '{{user `vsphere_username`}}' \\", | ||||
|           " -VSpherePassword '{{user `vsphere_password`}}'" | ||||
|         ] | ||||
|       } | ||||
|     ]] | ||||
| } | ||||
							
								
								
									
										27
									
								
								packer/preseed/ADCS/Sysprep_Unattend.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								packer/preseed/ADCS/Sysprep_Unattend.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <unattend xmlns="urn:schemas-microsoft-com:unattend"> | ||||
|     <settings pass="generalize"> | ||||
|         <component name="Microsoft-Windows-Security-SPP" 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"> | ||||
|             <SkipRearm>1</SkipRearm> | ||||
|         </component> | ||||
|         <component name="Microsoft-Windows-PnpSysprep" 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"> | ||||
|             <PersistAllDeviceInstalls>true</PersistAllDeviceInstalls> | ||||
|             <DoNotCleanUpNonPresentDevices>true</DoNotCleanUpNonPresentDevices> | ||||
|         </component> | ||||
|     </settings> | ||||
|     <settings pass="oobeSystem"> | ||||
|         <component name="Microsoft-Windows-Shell-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"> | ||||
|             <OOBE> | ||||
|                 <HideEULAPage>true</HideEULAPage> | ||||
|                 <HideLocalAccountScreen>true</HideLocalAccountScreen> | ||||
|                 <HideOEMRegistrationScreen>true</HideOEMRegistrationScreen> | ||||
|                 <HideOnlineAccountScreens>true</HideOnlineAccountScreens> | ||||
|                 <HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE> | ||||
|                 <NetworkLocation>Work</NetworkLocation> | ||||
|                 <ProtectYourPC>1</ProtectYourPC> | ||||
|                 <SkipMachineOOBE>true</SkipMachineOOBE> | ||||
|                 <SkipUserOOBE>true</SkipUserOOBE> | ||||
|             </OOBE> | ||||
|         </component> | ||||
|     </settings> | ||||
| </unattend> | ||||
							
								
								
									
										11
									
								
								packer/variables.vsphere.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								packer/variables.vsphere.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| { | ||||
|     "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" | ||||
| } | ||||
							
								
								
									
										48
									
								
								scripts/ADCS/Install-Prerequisites.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								scripts/ADCS/Install-Prerequisites.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,48 @@ | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     # No parameters | ||||
| ) | ||||
|  | ||||
| $InstallWindowsFeatureSplat = @{ | ||||
|     Name                   = 'Adcs-Cert-Authority' | ||||
|     IncludeAllSubFeature   = $True | ||||
|     IncludeManagementTools = $True | ||||
|     Restart                = $False | ||||
|     Confirm                = $False | ||||
| } | ||||
| Install-WindowsFeature @InstallWindowsFeatureSplat | ||||
|  | ||||
| $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               = 'powershell-yaml' | ||||
|     Force              = $True | ||||
|     Confirm            = $False | ||||
| } | ||||
| Install-Module @InstallModuleSplat | ||||
| $SetPSRepositorySplat = @{ | ||||
|     Name               = 'PSGallery' | ||||
|     InstallationPolicy = 'Untrusted' | ||||
| } | ||||
| Set-PSRepository @SetPSRepositorySplat | ||||
|  | ||||
| # Double check whether the required PowerShell modules are available | ||||
| $RequiredModules = @( | ||||
|     'powershell-yaml'   # Provides cmdlets 'ConvertTo-Yaml' and 'ConvertFrom-Yaml' | ||||
| ) | ||||
| ForEach ($Module in $RequiredModules) { | ||||
|     If ([boolean](Get-Module -Name $Module -ListAvailable) -ne $True) { | ||||
|         Write-Error -Message "Missing PowerShell module '$($Module)'" | ||||
|         Exit 1 | ||||
|     } | ||||
| } | ||||
							
								
								
									
										7
									
								
								scripts/ADCS/Register-ScheduledTask.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								scripts/ADCS/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" | ||||
							
								
								
									
										166
									
								
								scripts/ADCS/payload/Apply-OVFProperties.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								scripts/ADCS/payload/Apply-OVFProperties.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| #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 | ||||
| If (!($ovfPropertyValues['guestinfo.hostname'] -and | ||||
|     $ovfPropertyValues['guestinfo.ipaddress'] -and | ||||
|     $ovfPropertyValues['guestinfo.dnsserver'] -and | ||||
|     $ovfPropertyValues['guestinfo.prefixlength'] -and | ||||
|     $ovfPropertyValues['guestinfo.gateway'])) { | ||||
|         # Mandatory values missing, cannot provision. | ||||
|         $WriteEventLogSplat = @{ | ||||
|             LogName   = 'Application' | ||||
|             Source    = 'OVF-Properties' | ||||
|             EntryType = 'Error' | ||||
|             EventID   = 66 | ||||
|             Message   = 'Mandatory values missing, 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 | ||||
| } | ||||
|  | ||||
| # Foo | ||||
|  | ||||
| # 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 | ||||
							
								
								
									
										37
									
								
								scripts/ADCS/payload/scripts/01.Foo.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								scripts/ADCS/payload/scripts/01.Foo.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| #Requires -Modules 'NetSecurity' | ||||
| Param( | ||||
|     [Parameter(Mandatory)] | ||||
|     [hashtable]$Parameter | ||||
| ) | ||||
|  | ||||
| If ($False) { | ||||
|     $GetContentSplat = @{ | ||||
|         Path = "$($PSScriptRoot)\$($MyInvocation.MyCommand)".Replace('.ps1', '.yml') | ||||
|         Raw  = $true | ||||
|     } | ||||
|     $RawContent = Get-Content @GetContentSplat | ||||
|     $ConvertFromYamlSplat = @{ | ||||
|         Yaml         = $RawContent | ||||
|         AllDocuments = $True | ||||
|     } | ||||
|     $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 | ||||
|         $Settings = $YamlDocuments[0..($YamlDocuments.Count - 2)] | ||||
|     } | ||||
|     Else { | ||||
|         $Settings = $YamlDocuments | ||||
|     } | ||||
|  | ||||
|     #Foo | ||||
| } | ||||
							
								
								
									
										2
									
								
								scripts/ADCS/payload/scripts/01.Foo.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								scripts/ADCS/payload/scripts/01.Foo.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,2 @@ | ||||
| Foo: | ||||
| - Bar | ||||
							
								
								
									
										39
									
								
								scripts/Remove-Resources.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								scripts/Remove-Resources.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| [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 | ||||
|  | ||||
| $ConnectVIServerSplat = @{ | ||||
|     Server        = $VSphereFQDN | ||||
|     User          = "$VSphereUsername" | ||||
|     Password      = "$VSpherePassword" | ||||
|     WarningAction = 'SilentlyContinue' | ||||
| } | ||||
| Connect-VIServer @ConnectVIServerSplat | Out-Null | ||||
|  | ||||
| $RemoveVMSplat = @{ | ||||
|     VM                       = "$($VMName)*" | ||||
|     DeletePermanently        = $True | ||||
|     Confirm                  = $False | ||||
|     ErrorAction              = 'SilentlyContinue' | ||||
| } | ||||
| Remove-VM @RemoveVMSplat | ||||
|  | ||||
| # Also delete ISO/floppy? | ||||
|  | ||||
| Disconnect-VIServer * -Confirm:$False | ||||
							
								
								
									
										55
									
								
								scripts/Update-Manifest.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								scripts/Update-Manifest.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| #Requires -Modules 'powershell-yaml' | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     [Parameter(Mandatory)] | ||||
|     [ValidateScript({ | ||||
|             If (Test-Path($_)) { | ||||
|                 $True | ||||
|             } Else { | ||||
|                 Throw "'$_' is not a valid filename (within working directory '$PWD'), or access denied; aborting." | ||||
|             } | ||||
|         })] | ||||
|     [string]$ManifestFileName | ||||
| ) | ||||
|  | ||||
| $GetItemSplat = @{ | ||||
|     Path = $ManifestFileName | ||||
| } | ||||
| $ManifestFile = Get-Item @GetItemSplat | ||||
|  | ||||
| $SetLocationSplat = @{ | ||||
|     Path     = $ManifestFile.DirectoryName | ||||
| } | ||||
| Set-Location @SetLocationSplat | ||||
|  | ||||
| $GetContentSplat = @{ | ||||
|     Path = $ManifestFile.FullName | ||||
| } | ||||
| $Manifest = Get-Content @GetContentSplat | ||||
|  | ||||
| $UpdatedManifest = ForEach ($Line in $Manifest) { | ||||
|     Write-Host "Processing '$($Line)' ..." | ||||
|     If ($Line -match '^SHA256\((.+)\)= ([0-9a-fA-F]{64})$') { | ||||
|         If (Test-Path $Matches[1]) { | ||||
|             $GetFileHashSplat = @{ | ||||
|                 Path      = $Matches[1] | ||||
|                 Algorithm = 'SHA256' | ||||
|             } | ||||
|             Write-Host "Updating checksum..." | ||||
|             "SHA256($($Matches[1]))= $((Get-FileHash @GetFileHashSplat).Hash)" | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| If ($UpdatedManifest -ne $Null) { | ||||
|     $SetContentSplat = @{ | ||||
|         Path        = $ManifestFile.FullName | ||||
|         Value       = $UpdatedManifest | ||||
|         Force       = $True | ||||
|         Confirm     = $False | ||||
|     } | ||||
|     Set-Content @SetContentSplat     | ||||
| } Else { | ||||
|     Write-Host "Failed updating manifest." | ||||
|     Exit 1 | ||||
| } | ||||
							
								
								
									
										219
									
								
								scripts/Update-OvfConfiguration.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								scripts/Update-OvfConfiguration.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,219 @@ | ||||
| #Requires -Modules 'powershell-yaml' | ||||
| [CmdletBinding()] | ||||
| Param( | ||||
|     [Parameter(Mandatory)] | ||||
|     [ValidateScript({ | ||||
|             If (Test-Path($_)) { | ||||
|                 $True | ||||
|             } Else { | ||||
|                 Throw "'$_' is not a valid filename (within working directory '$PWD'), or access denied; aborting." | ||||
|             } | ||||
|         })] | ||||
|     [string]$OVFFile | ||||
| ) | ||||
|  | ||||
| $GetContentSplat = @{ | ||||
|     Path = "$($PSScriptRoot)\$($MyInvocation.MyCommand)".Replace('.ps1', ".yml") | ||||
|     Raw  = $True | ||||
| } | ||||
| $RawContent = Get-Content @GetContentSplat | ||||
| $ConvertFromYamlSplat = @{ | ||||
|     Yaml         = $RawContent | ||||
|     AllDocuments = $True | ||||
| } | ||||
| $OVFConfig = ConvertFrom-Yaml @ConvertFromYamlSplat | ||||
|  | ||||
| $SourceFile = Get-Item -Path $OVFFile | ||||
| $GetContentSplat = @{ | ||||
|     Path = $SourceFile.FullName | ||||
| } | ||||
| $XML = [xml](Get-Content @GetContentSplat) | ||||
| $NS = [System.Xml.XmlNamespaceManager]$XML.NameTable | ||||
| [void]$NS.AddNamespace('Any', $XML.DocumentElement.xmlns) | ||||
|  | ||||
| If ($OVFConfig.DeploymentConfigurations.Count -gt 0) { | ||||
|     $XMLSection = $XML.CreateElement('DeploymentOptionSection', $XML.DocumentElement.xmlns) | ||||
|     $XMLSectionInfo = $XML.CreateElement('Info', $XML.DocumentElement.xmlns) | ||||
|     $XMLSectionInfo.InnerText = 'Deployment Type' | ||||
|     [void]$XMLSection.AppendChild($XMLSectionInfo) | ||||
|      | ||||
|     ForEach ($Configuration in $OVFConfig.DeploymentConfigurations) { | ||||
|         $XMLConfig = $XML.CreateElement('Configuration', $XML.DocumentElement.xmlns) | ||||
|      | ||||
|         $XMLConfigAttrId = $XML.CreateAttribute('id', $XML.DocumentElement.ovf) | ||||
|         $XMLConfigAttrId.Value = $Configuration.Id | ||||
|      | ||||
|         $XMLConfigLabel = $XML.CreateElement('Label', $XML.DocumentElement.xmlns) | ||||
|         $XMLConfigLabel.InnerText = $Configuration.Label | ||||
|      | ||||
|         $XMLConfigDescription = $XML.CreateElement('Description', $XML.DocumentElement.xmlns) | ||||
|         $XMLConfigDescription.InnerText = $Configuration.Description | ||||
|      | ||||
|         [void]$XMLConfig.Attributes.Append($XMLConfigAttrId) | ||||
|         [void]$XMLConfig.AppendChild($XMLConfigLabel) | ||||
|         [void]$XMLConfig.AppendChild($XMLConfigDescription) | ||||
|      | ||||
|         [void]$XMLSection.AppendChild($XMLConfig) | ||||
|     } | ||||
|     [void]$XML.SelectSingleNode('//Any:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//Any:NetworkSection', $NS)) | ||||
|     Write-Host "Inserted 'DeploymentOptionSection' with $($Configuration.Count) nodes" | ||||
| } | ||||
|  | ||||
| $XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) | ||||
| $XMLAttrTransport.Value = 'com.vmware.guestInfo' | ||||
| [void]$XML.SelectSingleNode('//Any:VirtualHardwareSection', $NS).Attributes.Append($XMLAttrTransport) | ||||
|  | ||||
| $XMLProductSection = $XML.SelectSingleNode('//Any:ProductSection', $NS) | ||||
| If ($XMLProductSection -eq $Null) { | ||||
|     $XMLProductSection = $XML.CreateElement('ProductSection', $XML.DocumentElement.xmlns) | ||||
|     [void]$XML.SelectSingleNode('//Any:VirtualSystem', $NS).AppendChild($XMLProductSection) | ||||
|     Write-Host "Inserted 'ProductSection'" | ||||
| } Else { | ||||
|     ForEach ($Child in $XMLProductSection.SelectNodes('//Any:ProductSection/child::*', $NS)) { | ||||
|         [void]$Child.ParentNode.RemoveChild($Child) | ||||
|     } | ||||
|     Write-Host "Destroyed pre-existing children in 'ProductSection'" | ||||
| } | ||||
| $XMLProductSectionInfo = $XML.CreateElement('Info', $XML.DocumentElement.xmlns) | ||||
| $XMLProductSectionInfo.InnerText = 'Information about the installed software' | ||||
| [void]$XMLProductSection.AppendChild($XMLProductSectionInfo) | ||||
| Write-Host "Inserted new 'Info' into 'ProductSection'" | ||||
|  | ||||
| ForEach ($Category in $OVFConfig.PropertyCategories) { | ||||
|     If ($Category.Name -ne '') { | ||||
|         $XMLCategory = $XML.CreateElement('Category', $XML.DocumentElement.xmlns) | ||||
|         $XMLCategory.InnerText = $Category.Name | ||||
|         [void]$XMLProductSection.AppendChild($XMLCategory) | ||||
|         Write-Host "Inserted new 'Category' into 'ProductSection'" | ||||
|     } | ||||
|  | ||||
|     ForEach ($Property in $Category.ProductProperties) { | ||||
|         $XMLProperty = $XML.CreateElement('Property', $XML.DocumentElement.xmlns) | ||||
|      | ||||
|         $XMLPropertyAttrKey = $XML.CreateAttribute('key', $XML.DocumentElement.ovf) | ||||
|         $XMLPropertyAttrKey.Value = $Property.Key | ||||
|         $XMLPropertyAttrType = $XML.CreateAttribute('type', $XML.DocumentElement.ovf) | ||||
|         Switch -regex ($Property.Type) { | ||||
|             'boolean' { | ||||
|                 $XMLPropertyAttrType.Value = 'boolean' | ||||
|             } | ||||
|             'int' { | ||||
|                 $XMLPropertyAttrType.Value = 'uint8' | ||||
|                 $Qualifiers = @() | ||||
|                 If ($Property.Type -match 'int\((\d*)\.\.(\d*)\)') { | ||||
|                     If ($Matches[1]) { | ||||
|                         $Qualifiers += "MinValue($($Matches[1]))" | ||||
|                     } | ||||
|                     If ($Matches[2]) { | ||||
|                         $Qualifiers += "MaxValue($($Matches[2]))" | ||||
|                     } | ||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||
|                     $XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' ' | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } | ||||
|             } | ||||
|             'ip' { | ||||
|                 $XMLPropertyAttrType.Value = 'string' | ||||
|                 $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.vmw) | ||||
|                 $XMLPropertyAttrQualifiers.Value = 'Ip' | ||||
|                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|             } | ||||
|             'password' { | ||||
|                 $XMLPropertyAttrType.Value = 'string' | ||||
|                 $XMLPropertyAttrPassword = $XML.CreateAttribute('password', $XML.DocumentElement.ovf) | ||||
|                 $XMLPropertyAttrPassword.Value = 'true' | ||||
|                 [void]$XMLProperty.Attributes.Append($XMLPropertyAttrPassword) | ||||
|  | ||||
|                 $Qualifiers = @() | ||||
|                 If ($Property.Type -match 'password\((\d*)\.\.(\d*)\)') { | ||||
|                     If ($Matches[1]) { | ||||
|                         $Qualifiers += "MinLen($($Matches[1]))" | ||||
|                     } | ||||
|                     If ($Matches[2]) { | ||||
|                         $Qualifiers += "MaxLen($($Matches[2]))" | ||||
|                     } | ||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||
|                     $XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' ' | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } | ||||
|             } | ||||
|             'string' { | ||||
|                 $XMLPropertyAttrType.Value = 'string' | ||||
|                 $Qualifiers = @() | ||||
|                 If ($Property.Type -match 'string\((\d*)\.\.(\d*)\)') { | ||||
|                     If ($Matches[1]) { | ||||
|                         $Qualifiers += "MinLen($($Matches[1]))" | ||||
|                     } | ||||
|                     If ($Matches[2]) { | ||||
|                         $Qualifiers += "MaxLen($($Matches[2]))" | ||||
|                     } | ||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||
|                     $XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' ' | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } ElseIf ($Property.Type -match 'string\[(.*)\]') { | ||||
|                     $XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) | ||||
|                     $XMLPropertyAttrQualifiers.Value = "ValueMap{$($Matches[1] -replace '","', '", "')}" | ||||
|                     [void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         $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') { | ||||
|             $XMLPropertyAttrValue.Value = "$([boolean]$Property.DefaultValue)".ToLower() | ||||
|         } Else { | ||||
|             $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) { | ||||
|             $XMLPropertyLabel = $XML.CreateElement('Label', $XML.DocumentElement.xmlns) | ||||
|             $XMLPropertyLabel.InnerText = $Property.Label | ||||
|             [void]$XMLProperty.AppendChild($XMLPropertyLabel) | ||||
|         } | ||||
|         If ($Property.Description) { | ||||
|             $XMLPropertyDescription = $XML.CreateElement('Description', $XML.DocumentElement.xmlns) | ||||
|             $XMLPropertyDescription.InnerText = $Property.Description | ||||
|             [void]$XMLProperty.AppendChild($XMLPropertyDescription) | ||||
|         } | ||||
|  | ||||
|         If (($Property.Configurations.Count -eq 1) -and ($Property.Configurations -eq '*')) { | ||||
|             $XMLPropertyAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf) | ||||
|             $XMLPropertyAttrConfiguration.Value = $OVFConfig.DeploymentConfigurations.Id -join ' ' | ||||
|             [void]$XMLProperty.Attributes.Append($XMLPropertyAttrConfiguration)        | ||||
|         } ElseIf ($Property.Configurations.Count -gt 0) { | ||||
|             $XMLPropertyAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf) | ||||
|             $XMLPropertyAttrConfiguration.Value = $Property.Configurations -join ' ' | ||||
|             [void]$XMLProperty.Attributes.Append($XMLPropertyAttrConfiguration)        | ||||
|         } | ||||
|  | ||||
|         If ($Property.Value.Count -eq 1) { | ||||
|             $XMLPropertyAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf) | ||||
|             $XMLPropertyAttrValue.Value = $Property.Value | ||||
|             [void]$XMLProperty.Attributes.Append($XMLPropertyAttrValue)        | ||||
|         } ElseIf ($Property.Value.Count -gt 1) { | ||||
|             ForEach ($Value in $Property.Value) { | ||||
|                 $XMLValue = $XML.CreateElement('Value', $XML.DocumentElement.xmlns) | ||||
|  | ||||
|                 $XMLValueAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf) | ||||
|                 $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]$XMLProductSection.AppendChild($XMLProperty) | ||||
|     } | ||||
|     Write-Host "Inserted $($Category.ProductProperties.Count) new node(s) into 'ProductSection'" | ||||
| } | ||||
|  | ||||
| $XML.Save($SourceFile.FullName) | ||||
							
								
								
									
										75
									
								
								scripts/Update-OvfConfiguration.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								scripts/Update-OvfConfiguration.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| DeploymentConfigurations: | ||||
| - Id: standalone-root | ||||
|   Label: Root Certificate Authority | ||||
|   Description: Root CA with self-signed certificate; should be kept turned off | ||||
| - Id: enterprise-intermediate | ||||
|   Label: Subordinate enterprise Certificate Authority | ||||
|   Description: Subordinate CA on domain-member server; kept online to service certificate requests/enrollment and host CRL | ||||
| - Id: standalone-intermediate | ||||
|   Label: Subordinate standalone Certificate Authority | ||||
|   Description: Subordinate CA on standalone server; kept online to service certificate requests and host CRL | ||||
| PropertyCategories: | ||||
| - Name: '' | ||||
|   ProductProperties: | ||||
|   - Key: deployment.type | ||||
|     Type: string | ||||
|     Value: | ||||
|     - standalone-root | ||||
|     - enterprise-intermediate | ||||
|     - standalone-intermediate | ||||
|     UserConfigurable: false | ||||
| - Name: 1) Operating System | ||||
|   ProductProperties: | ||||
|   - Key: guestinfo.hostname | ||||
|     Type: string(1..15) | ||||
|     Label: Hostname* | ||||
|     Description: '(max length: 15 characters)' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
| - Name: 2) Networking | ||||
|   ProductProperties: | ||||
|   - Key: guestinfo.ipaddress | ||||
|     Type: ip | ||||
|     Label: IP Address* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.prefixlength | ||||
|     Type: int(8..32) | ||||
|     Label: Subnet prefix length* | ||||
|     Description: '' | ||||
|     DefaultValue: '24' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.dnsserver | ||||
|     Type: ip | ||||
|     Label: DNS server* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: guestinfo.gateway | ||||
|     Type: ip | ||||
|     Label: Gateway* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
| - Name: 3) Active Directory Certificate Services | ||||
|   ProductProperties: | ||||
|   - Key: adcsconfig.foo | ||||
|     Type: string(1..) | ||||
|     Label: Foo* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
|   - Key: adcsconfig.bar | ||||
|     Type: string(1..) | ||||
|     Label: Bar* | ||||
|     Description: '' | ||||
|     DefaultValue: '' | ||||
|     Configurations: '*' | ||||
|     UserConfigurable: true | ||||
		Reference in New Issue
	
	Block a user