81 Commits
Author SHA1 Message Date
djpbessems 98a6e636fb Revert package manager (not compatible with winRM!!!)
continuous-integration/drone/push Build is passing
2021-07-05 17:07:04 +02:00
djpbessems a3e4fb98eb Attempt package manager installation with provided license
continuous-integration/drone/push Build is passing
2021-07-05 15:52:43 +02:00
djpbessems b041658fbf Testing wrt VMware Tools auto-start
continuous-integration/drone/push Build is failing
2021-06-29 13:12:10 +02:00
djpbessems 6a18b5bf22 Adjust package manager install to new release format
continuous-integration/drone/push Build is failing
2021-06-25 15:08:03 +02:00
djpbessems de5546f776 Try once more to switch package manager
continuous-integration/drone/push Build is passing
2021-06-25 12:39:39 +02:00
djpbessems c262c55e06 Fix paths (forgot to stage the changes in previous commit :P)
continuous-integration/drone/push Build is failing
2021-06-24 13:25:30 +02:00
djpbessems 567e7e64f9 Housekeeping;Add prereq module installation
continuous-integration/drone/push Build is failing
2021-06-24 10:14:22 +02:00
djpbessems 16575d1db4 Disable baremetal for now;Add to package manager install logic
continuous-integration/drone/push Build is failing
2021-06-24 09:26:21 +02:00
djpbessems 0c19c023de Fix pvscsi dedicated xml reference
continuous-integration/drone/push Build was killed
2021-06-24 09:03:06 +02:00
djpbessems 0958d6a352 Retry winget package manager
continuous-integration/drone/push Build is failing
2021-06-23 21:55:07 +02:00
djpbessems 8f1dd67224 Reorder autounattend.xml #2
continuous-integration/drone/push Build was killed
2021-06-23 13:01:23 +02:00
djpbessems 67d70f58f8 Try more elaborate autounattend configuration
continuous-integration/drone/push Build was killed
2021-06-23 12:53:34 +02:00
djpbessems 9868c43b14 Change autounattend XML order
continuous-integration/drone/push Build is running
2021-06-23 09:44:11 +02:00
djpbessems 11ea6f68ee Specify pvscsi drivers
continuous-integration/drone/push Build was killed
2021-06-23 09:30:15 +02:00
djpbessems e5487a22f3 Try pvscsi controller without extra drivers
continuous-integration/drone/push Build was killed
2021-06-23 09:05:17 +02:00
djpbessems 2487003d08 Change controller for baremetal
continuous-integration/drone/push Build is failing
2021-06-22 19:40:08 +02:00
djpbessems 5597046178 Revert package manager to chocolatey 2021-06-22 16:41:19 +02:00
djpbessems 6228c8db35 Decrease packer VM RAM
continuous-integration/drone/push Build is passing
2021-06-22 15:47:47 +02:00
djpbessems 84d449dadb Fix dependencies for package manager
continuous-integration/drone/push Build is passing
2021-06-22 13:44:06 +02:00
djpbessems 51f6a7c7bd Force pull container image
continuous-integration/drone/push Build is passing
2021-06-22 11:23:43 +02:00
djpbessems 248ac46d5f Fix typo 2021-06-22 10:36:21 +02:00
djpbessems 5b0a8fc7df Fix path #2;Change package manager
continuous-integration/drone/push Build is failing
2021-06-22 09:54:45 +02:00
djpbessems 83baeefea0 Fix paths
continuous-integration/drone/push Build is failing
2021-06-21 16:33:11 +02:00
djpbessems 1459e6dead Move iso details to separate file;Add baremetal builder/source
continuous-integration/drone/push Build is failing
2021-06-21 09:28:22 +02:00
djpbessems 1e699d62a2 Fix 'only' key references
continuous-integration/drone/push Build is passing
2021-06-07 15:42:14 +02:00
djpbessems 1e885beb45 Fix plugin version constraint
continuous-integration/drone/push Build is passing
2021-06-04 22:39:31 +02:00
djpbessems 01e2fff44f Remove redundand feedback 2021-06-04 22:35:26 +02:00
djpbessems fa6f029812 Housekeeping; Add debugging information
continuous-integration/drone/push Build is passing
2021-06-04 22:31:04 +02:00
djpbessems ca2d75d18b Remove redundant files 2021-06-04 20:12:16 +02:00
djpbessems 3334ec7117 Fix syntax according to HCL
continuous-integration/drone/push Build is passing
2021-06-04 19:20:25 +02:00
djpbessems 1ce40f2a5a Add variable definitions #2
continuous-integration/drone/push Build is failing
2021-06-04 17:22:54 +02:00
djpbessems 64fd9a195f Add variable definitions
continuous-integration/drone/push Build is failing
2021-06-04 17:15:59 +02:00
djpbessems b3e7070f6e Migrate to .hcl;Add new packer init step
continuous-integration/drone/push Build is failing
2021-06-04 16:41:43 +02:00
djpbessems 22f7a433f7 Cleanup deployment options w/ sizes
continuous-integration/drone/push Build is passing
2021-05-19 15:22:17 +02:00
djpbessems 6c3d8706b8 Fix missing bracket
continuous-integration/drone/push Build is passing
2021-05-19 11:11:09 +02:00
djpbessems 865eeaa165 Order XML elements properly according to OVF best practices
continuous-integration/drone/push Build is passing
2021-05-19 10:03:52 +02:00
djpbessems 074865ab61 Housekeeping wrt comments;Several code optimizations
continuous-integration/drone/push Build is passing
2021-05-12 15:25:29 +02:00
djpbessems 969e3b385b Fix XML root element references;Deleted comments
continuous-integration/drone/push Build is passing
2021-05-12 12:54:11 +02:00
djpbessems 8340b97a4d Simplify code (different method for XML attributes)
continuous-integration/drone/push Build is failing
2021-05-12 11:38:39 +02:00
djpbessems ddf8b2e7cf Add namespace declaration for XML attribute
continuous-integration/drone/push Build is passing
2021-05-12 09:53:10 +02:00
djpbessems 0fc1cb12c7 Remove ReferencedDisks;Add missing resourceType=17 XML items
continuous-integration/drone/push Build is passing
2021-05-11 15:13:14 +02:00
djpbessems 5cf101d641 Introduce sized deployment options
continuous-integration/drone/push Build is passing
2021-05-11 13:00:12 +02:00
djpbessems 68f5b15d67 Fix default int to 16-bit
continuous-integration/drone/push Build is passing
2021-05-11 11:56:11 +02:00
djpbessems ec1aa6ab85 Fix XML method invocation
continuous-integration/drone/push Build is passing
2021-05-11 09:00:32 +02:00
djpbessems d1413040fe Append new nodes into XML parent node; Fix capacity comparison.
continuous-integration/drone/push Build is failing
2021-05-10 23:13:04 +02:00
djpbessems a7ded04317 Fix missing XML namespace
continuous-integration/drone/push Build is passing
2021-05-10 16:27:49 +02:00
djpbessems 454b5e92b0 First draft of disk(re)sizing
continuous-integration/drone/push Build is passing
2021-05-10 15:17:29 +02:00
djpbessems d13e2a2ed6 Fix yamllint errors
continuous-integration/drone/push Build is passing
2021-04-09 12:49:55 +02:00
djpbessems 34e14e721f Add yamllint;Replay downstream changes
continuous-integration/drone/push Build is failing
2021-04-09 11:43:42 +02:00
djpbessems 8f54a61482 Abandon attempts to install Edge; Add Firefox
continuous-integration/drone/push Build is passing
2021-04-02 16:33:10 +02:00
djpbessems 77d329c0b6 Debug Edge installer #3
continuous-integration/drone/push Build is failing
2021-04-02 15:50:50 +02:00
djpbessems eab16f120a Debug Edge installer #2
continuous-integration/drone/push Build is failing
2021-04-02 14:48:57 +02:00
djpbessems d14f81a481 Debug Edge installer 2021-04-02 14:47:06 +02:00
djpbessems 34d79cedf8 Remove redundant files;Apply MSI transform to Edge
continuous-integration/drone/push Build is failing
2021-04-02 13:50:56 +02:00
djpbessems c8a6d7b3fd Change datastore
continuous-integration/drone/push Build is failing
2021-04-02 11:22:03 +02:00
djpbessems 893ff3f8c6 Add Microsoft Edge
continuous-integration/drone/push Build is failing
2021-04-02 10:52:53 +02:00
djpbessems fdf132cbab Update hypervisor host FQDN #2
continuous-integration/drone/push Build is passing
2021-03-24 13:59:24 +01:00
djpbessems 0a1075c84d Update hypervisor FQDN
continuous-integration/drone/push Build is failing
2021-03-24 11:28:17 +01:00
djpbessems 7cc631b378 Fix switch regex match
continuous-integration/drone/push Build is failing
2021-03-24 11:26:05 +01:00
djpbessems d67158b171 Fix loop waiting for network
continuous-integration/drone/push Build is passing
2021-02-19 21:16:30 +01:00
djpbessems dd842daca0 Remove stray module requirement
continuous-integration/drone/push Build is passing
2021-02-19 11:09:06 +01:00
djpbessems c7e4fd833b Always perform cleanup
continuous-integration/drone/push Build is passing
2021-02-15 12:12:20 +01:00
djpbessems 4ad5c365d6 Fix quotes
continuous-integration/drone/push Build is passing
2021-02-14 22:19:03 +01:00
djpbessems 301f974faa Fix stray comma
continuous-integration/drone/push Build is passing
2021-02-14 17:21:55 +01:00
djpbessems 485a318bcb Move cleanup to seperate build step
continuous-integration/drone/push Build is failing
2021-02-14 13:22:34 +01:00
djpbessems b3e33a7027 Avoid race condition between builders
continuous-integration/drone/push Build is passing
2021-02-14 12:32:40 +01:00
djpbessems 7d969cc0f4 Fix typo
continuous-integration/drone/push Build is failing
2021-02-14 09:52:30 +01:00
djpbessems 8bf25b5f55 Fix VM name;Fix cmdlet param;Purge scratch folder
continuous-integration/drone/push Build is passing
2021-02-13 22:07:01 +01:00
djpbessems 961624998b Fix path;Add conditional
continuous-integration/drone/push Build is failing
2021-02-13 20:16:31 +01:00
djpbessems 2790b9c9d9 Fix volume name
continuous-integration/drone/push Build is failing
2021-02-13 10:48:44 +01:00
djpbessems b09801282f Move temporary files to separate volume scratch
continuous-integration/drone/push Build was killed
2021-02-13 10:46:43 +01:00
djpbessems af8249d1a7 Debug volume
continuous-integration/drone/push Build encountered an error
2021-02-13 10:16:18 +01:00
djpbessems fe0341effb Revert parallelism;Show timestamps;Workspace-vol
continuous-integration/drone/push Build encountered an error
2021-02-13 09:59:16 +01:00
djpbessems b3f358953b Limit parallel builds due to resource congestion
continuous-integration/drone/push Build was killed
2021-02-12 20:57:53 +01:00
djpbessems e10c265676 Fix path
continuous-integration/drone/push Build was killed
2021-02-12 17:02:05 +01:00
djpbessems 28b6ae7444 Add payload Server2019;Add intermediate template
continuous-integration/drone/push Build is failing
2021-02-12 16:44:39 +01:00
djpbessems 3a608d878d Housekeeping;Match packer template w/ prod pipeline
continuous-integration/drone/push Build is passing
2021-02-10 10:04:04 +01:00
djpbessems e8b41ba5a4 Add XML excerpt and screenshots to documentation
continuous-integration/drone/push Build is passing
2021-02-04 12:09:29 +01:00
djpbessems fed9292100 Add two DeploymentOptions w/ distinct vApp props
continuous-integration/drone/push Build is passing
2021-02-03 12:55:17 +01:00
djpbessems c1eeaa9f7f Update badge in README
continuous-integration/drone/push Build is passing
2021-01-27 21:32:16 +01:00
djpbessems 02907e7c65 Delete commit history (containing proprietary code)
continuous-integration/drone/push Build is passing
2021-01-23 15:59:06 +01:00
54 changed files with 934 additions and 461 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

+24 -9
View File
@@ -13,20 +13,22 @@ 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
- pwsh --version - qemu-img --version
- ovftool --version - ovftool --version
- name: Windows 10 - pwsh --version
- name: Windows Server 2019
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/Windows10/Autounattend.xml - sed -i -e "s/<<img-productkey>>/$${PRODUCTKEY}/" packer/preseed/Server2019/Autounattend.xml
- | - |
sed -i -e "s/<<img-password>>/$${WINRM_PASSWORD}/g" \ sed -i -e "s/<<img-password>>/$${WINRM_PASSWORD}/g" \
packer/preseed/Windows10/Autounattend.xml \ packer/preseed/Server2019/Autounattend.xml \
packer/preseed/Windows10/Sysprep_Unattend.xml packer/preseed/Server2019/Sysprep_Unattend.xml
- | - |
yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts yamllint -d "{extends: relaxed, rules: {line-length: disable}}" scripts
- | - |
@@ -35,7 +37,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=win10 \ -var vm_guestos=server2019 \
-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} \
@@ -43,9 +45,9 @@ steps:
./packer ./packer
- | - |
packer build \ packer build \
-on-error=cleanup \ -on-error=cleanup -timestamp-ui \
-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=win10 \ -var vm_guestos=server2019 \
-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} \
@@ -61,13 +63,16 @@ steps:
REPO_PASSWORD: REPO_PASSWORD:
from_secret: repo_password from_secret: repo_password
PRODUCTKEY: PRODUCTKEY:
from_secret: prodkey_win10 from_secret: prodkey_server2019
# 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 \
@@ -85,3 +90,13 @@ 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
+85 -1
View File
@@ -1 +1,85 @@
# 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) # 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)
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
@@ -1,16 +0,0 @@
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
@@ -1,29 +0,0 @@
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
@@ -1,29 +0,0 @@
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
@@ -1,54 +0,0 @@
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
@@ -1,10 +0,0 @@
---
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
@@ -0,0 +1,5 @@
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"
]
@@ -19,7 +19,7 @@
<Letter>C</Letter> <Letter>C</Letter>
<Order>1</Order> <Order>1</Order>
<PartitionID>1</PartitionID> <PartitionID>1</PartitionID>
<Label>Windows 10</Label> <Label>Windows Server 2019</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>3</Value> <Value>4</Value>
</MetaData> </MetaData>
</InstallFrom> </InstallFrom>
</OSImage> </OSImage>
@@ -0,0 +1,168 @@
<?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>
+9
View File
@@ -3,6 +3,7 @@ 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" {}
@@ -14,5 +15,13 @@ 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,6 +2,7 @@ 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
@@ -1,133 +0,0 @@
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
@@ -0,0 +1,313 @@
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
@@ -0,0 +1,40 @@
[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
@@ -0,0 +1,74 @@
#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
@@ -1,73 +0,0 @@
<?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.
+134 -75
View File
@@ -47,7 +47,77 @@ $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('Any', $XML.DocumentElement.xmlns) [void]$NS.AddNamespace('ns', $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)
@@ -58,52 +128,72 @@ 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)
$XMLConfigAttrId = $XML.CreateAttribute('id', $XML.DocumentElement.ovf) [void]$XMLConfig.SetAttribute('id', $NS.LookupNamespace('ovf'), $Configuration.Id)
$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('//Any:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//Any:NetworkSection', $NS)) [void]$XML.SelectSingleNode('//ns:Envelope', $NS).InsertAfter($XMLSection, $XML.SelectSingleNode('//ns: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)
)
}
}
} }
$XMLAttrTransport = $XML.CreateAttribute('transport', $XML.DocumentElement.ovf) [void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).SetAttribute('transport', $NS.LookupNamespace('ovf'), 'com.vmware.guestInfo')
$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)
$XMLExtraConfigAttrRequired = $XML.CreateAttribute('required', $XML.DocumentElement.ovf) [void]$XMLExtraConfig.SetAttribute('required', $NS.LookupNamespace('ovf'), "$([boolean]$ExtraConfig.Required)".ToLower())
$XMLExtraConfigAttrRequired.Value = "$([boolean]$ExtraConfig.Required)".ToLower() [void]$XMLExtraConfig.SetAttribute('key', $NS.LookupNamespace('vmw'), $ExtraConfig.Key)
$XMLExtraConfigAttrKey = $XML.CreateAttribute('key', $XML.DocumentElement.vmw) [void]$XMLExtraConfig.SetAttribute('value', $NS.LookupNamespace('vmw'), $ExtraConfig.Value)
$XMLExtraConfigAttrKey.Value = $ExtraConfig.Key
$XMLExtraConfigAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.vmw)
$XMLExtraConfigAttrValue.Value = $ExtraConfig.Value
[void]$XMLExtraConfig.Attributes.Append($XMLExtraConfigAttrRequired) [void]$XML.SelectSingleNode('//ns:VirtualHardwareSection', $NS).AppendChild($XMLExtraConfig)
[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' nodes" Write-Host "Added $($OVFConfig.AdvancedOptions.Count) 'vmw:ExtraConfig' node(s)"
$XMLProductSection = $XML.SelectSingleNode('//Any:ProductSection', $NS) $XMLProductSection = $XML.SelectSingleNode('//ns: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('//Any:VirtualSystem', $NS).AppendChild($XMLProductSection) [void]$XML.SelectSingleNode('//ns:VirtualSystem', $NS).AppendChild($XMLProductSection)
Write-Host "Inserted 'ProductSection'" Write-Host "Inserted 'ProductSection'"
} Else { } Else {
ForEach ($Child in $XMLProductSection.SelectNodes('//Any:ProductSection/child::*', $NS)) { ForEach ($Child in $XMLProductSection.SelectNodes('//ns: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'"
@@ -124,15 +214,13 @@ 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)
$XMLPropertyAttrKey = $XML.CreateAttribute('key', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('key', $NS.LookupNamespace('ovf'), $Property.Key)
$XMLPropertyAttrKey.Value = $Property.Key
$XMLPropertyAttrType = $XML.CreateAttribute('type', $XML.DocumentElement.ovf)
Switch -regex ($Property.Type) { Switch -regex ($Property.Type) {
'^boolean' { '^boolean' {
$XMLPropertyAttrType.Value = 'boolean' [void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'boolean')
} }
'^int' { '^int' {
$XMLPropertyAttrType.Value = 'uint8' [void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'uint16')
$Qualifiers = @() $Qualifiers = @()
If ($Property.Type -match '^int\((\d*)\.\.(\d*)\)') { If ($Property.Type -match '^int\((\d*)\.\.(\d*)\)') {
If ($Matches[1]) { If ($Matches[1]) {
@@ -141,23 +229,16 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
If ($Matches[2]) { If ($Matches[2]) {
$Qualifiers += "MaxValue($($Matches[2]))" $Qualifiers += "MaxValue($($Matches[2]))"
} }
$XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), $Qualifiers -join ' ')
$XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
} }
'^ip' { '^ip' {
$XMLPropertyAttrType.Value = 'string' [void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'string')
$XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.vmw) [void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('vmw'), 'Ip')
$XMLPropertyAttrQualifiers.Value = 'Ip'
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
'^password' { '^password' {
$XMLPropertyAttrType.Value = 'string' [void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'string')
$XMLPropertyAttrPassword = $XML.CreateAttribute('password', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('password', $NS.LookupNamespace('ovf'), 'true')
$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]) {
@@ -166,13 +247,11 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
If ($Matches[2]) { If ($Matches[2]) {
$Qualifiers += "MaxLen($($Matches[2]))" $Qualifiers += "MaxLen($($Matches[2]))"
} }
$XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), $Qualifiers -join ' ')
$XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
} }
'^string' { '^string' {
$XMLPropertyAttrType.Value = 'string' [void]$XMLProperty.SetAttribute('type', $NS.LookupNamespace('ovf'), 'string')
$Qualifiers = @() $Qualifiers = @()
If ($Property.Type -match '^string\((\d*)\.\.(\d*)\)') { If ($Property.Type -match '^string\((\d*)\.\.(\d*)\)') {
If ($Matches[1]) { If ($Matches[1]) {
@@ -181,28 +260,19 @@ ForEach ($Category in $OVFConfig.PropertyCategories) {
If ($Matches[2]) { If ($Matches[2]) {
$Qualifiers += "MaxLen($($Matches[2]))" $Qualifiers += "MaxLen($($Matches[2]))"
} }
$XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), $Qualifiers -join ' ')
$XMLPropertyAttrQualifiers.Value = $Qualifiers -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} ElseIf ($Property.Type -match '^string\[(.*)\]') { } ElseIf ($Property.Type -match '^string\[(.*)\]') {
$XMLPropertyAttrQualifiers = $XML.CreateAttribute('qualifiers', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('qualifiers', $NS.LookupNamespace('ovf'), "ValueMap{$($Matches[1] -replace '","', '", "')}")
$XMLPropertyAttrQualifiers.Value = "ValueMap{$($Matches[1] -replace '","', '", "')}"
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrQualifiers)
} }
} }
} }
$XMLPropertyAttrUserConfigurable = $XML.CreateAttribute('userConfigurable', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('userConfigurable', $NS.LookupNamespace('ovf'), "$([boolean]$Property.UserConfigurable)".ToLower())
$XMLPropertyAttrUserConfigurable.Value = "$([boolean]$Property.UserConfigurable)".ToLower()
$XMLPropertyAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf)
If ($Property.Type -eq 'boolean') { If ($Property.Type -eq 'boolean') {
$XMLPropertyAttrValue.Value = "$([boolean]$Property.DefaultValue)".ToLower() [void]$XMLProperty.SetAttribute('value', $NS.LookupNamespace('ovf'), "$([boolean]$Property.DefaultValue)".ToLower())
} Else { } Else {
$XMLPropertyAttrValue.Value = $Property.DefaultValue [void]$XMLProperty.SetAttribute('value', $NS.LookupNamespace('ovf'), $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)
@@ -216,30 +286,19 @@ 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 '*')) {
$XMLPropertyAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $OVFConfig.DeploymentConfigurations.Id -join ' ')
$XMLPropertyAttrConfiguration.Value = $OVFConfig.DeploymentConfigurations.Id -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrConfiguration)
} ElseIf ($Property.Configurations.Count -gt 0) { } ElseIf ($Property.Configurations.Count -gt 0) {
$XMLPropertyAttrConfiguration = $XML.CreateAttribute('configuration', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $Property.Configurations -join ' ')
$XMLPropertyAttrConfiguration.Value = $Property.Configurations -join ' '
[void]$XMLProperty.Attributes.Append($XMLPropertyAttrConfiguration)
} }
If ($Property.Value.Count -eq 1) { If ($Property.Value.Count -eq 1) {
$XMLPropertyAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf) [void]$XMLProperty.SetAttribute('value', $NS.LookupNamespace('ovf'), $Property.Value)
$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)
$XMLValueAttrValue = $XML.CreateAttribute('value', $XML.DocumentElement.ovf) [void]$XMLValue.SetAttribute('value', $NS.LookupNamespace('ovf'), $Value)
$XMLValueAttrValue.Value = $Value [void]$XMLValue.SetAttribute('configuration', $NS.LookupNamespace('ovf'), $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)
} }
+68 -13
View File
@@ -1,18 +1,63 @@
DeploymentConfigurations: DeploymentConfigurations:
- Id: domainmember - Id: domainmember-small
Label: Domain member Label: 'Domain member [SMALL: 1 vCPU/2GB RAM]'
Description: Windows 10 client joined to an Active Directory domain Description: Windows Server joined to an Active Directory domain.
- Id: standalone Size:
Label: Stand-alone CPU: 1
Description: Stand-alone Windows 10 client Memory: 2048
- 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 - domainmember-small
- standalone - domainmember-medium
- domainmember-large
- standalone-small
- standalone-medium
- standalone-large
UserConfigurable: false UserConfigurable: false
- Name: 1) Operating System - Name: 1) Operating System
ProductProperties: ProductProperties:
@@ -29,7 +74,9 @@ PropertyCategories:
Description: Must meet password complexity rules Description: Must meet password complexity rules
DefaultValue: password DefaultValue: password
Configurations: Configurations:
- standalone - standalone-small
- standalone-medium
- standalone-large
UserConfigurable: true UserConfigurable: true
- Key: guestinfo.ntpserver - Key: guestinfo.ntpserver
Type: string(1..) Type: string(1..)
@@ -37,7 +84,9 @@ 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 - standalone-small
- standalone-medium
- standalone-large
UserConfigurable: true UserConfigurable: true
- Name: 2) Networking - Name: 2) Networking
ProductProperties: ProductProperties:
@@ -77,7 +126,9 @@ 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 - domainmember-small
- domainmember-medium
- domainmember-large
UserConfigurable: true UserConfigurable: true
- Key: addsconfig.username - Key: addsconfig.username
Type: string(1..) Type: string(1..)
@@ -85,7 +136,9 @@ PropertyCategories:
Description: '' Description: ''
DefaultValue: username DefaultValue: username
Configurations: Configurations:
- domainmember - domainmember-small
- domainmember-medium
- domainmember-large
UserConfigurable: true UserConfigurable: true
- Key: addsconfig.password - Key: addsconfig.password
Type: password(1..) Type: password(1..)
@@ -93,7 +146,9 @@ PropertyCategories:
Description: '' Description: ''
DefaultValue: password DefaultValue: password
Configurations: Configurations:
- domainmember - domainmember-small
- 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 ($ovfPropertyValues['deployment.type']) { Switch -regex ($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 ($ovfPropertyValues['deployment.type']) { Switch -regex ($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 ($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,12 +192,6 @@ Switch ($ovfPropertyValues['deployment.type']) {
Confirm = $False Confirm = $False
} }
Set-LocalUser @SetLocalUserSplat Set-LocalUser @SetLocalUserSplat
$EnableLocalUserSplat = @{
InputObject = $BuiltinAdministrator
Confirm = $False
}
Enable-LocalUser @EnableLocalUserSplat
} }
} }