Add template for Windows Server 2022
This commit is contained in:
346
ws2022/answer_files/Autounattend.xml.pkrtpl
Normal file
346
ws2022/answer_files/Autounattend.xml.pkrtpl
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<unattend
|
||||||
|
xmlns="urn:schemas-microsoft-com:unattend"
|
||||||
|
xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<!-- windowsPE: disk layout, drivers, image selection -->
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<settings pass="windowsPE">
|
||||||
|
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-International-Core-WinPE"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<SetupUILanguage>
|
||||||
|
<UILanguage>${locale}</UILanguage>
|
||||||
|
</SetupUILanguage>
|
||||||
|
<InputLocale>${locale}</InputLocale>
|
||||||
|
<SystemLocale>${locale}</SystemLocale>
|
||||||
|
<UILanguage>${locale}</UILanguage>
|
||||||
|
<UserLocale>${locale}</UserLocale>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<!-- Load VirtIO drivers into WinPE so the installer can see SCSI disks and network -->
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-PnpCustomizationsWinPE"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<DriverPaths>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
|
||||||
|
<Path>${virtio_drive}:\vioscsi\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="2">
|
||||||
|
<Path>${virtio_drive}:\viostor\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="3">
|
||||||
|
<Path>${virtio_drive}:\NetKVM\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
</DriverPaths>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-Setup"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
|
||||||
|
<!-- UEFI GPT disk layout -->
|
||||||
|
<DiskConfiguration>
|
||||||
|
<Disk wcm:action="add">
|
||||||
|
<DiskID>0</DiskID>
|
||||||
|
<WillWipeDisk>true</WillWipeDisk>
|
||||||
|
<CreatePartitions>
|
||||||
|
<CreatePartition wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<Type>EFI</Type>
|
||||||
|
<Size>100</Size>
|
||||||
|
</CreatePartition>
|
||||||
|
<CreatePartition wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<Type>MSR</Type>
|
||||||
|
<Size>128</Size>
|
||||||
|
</CreatePartition>
|
||||||
|
<CreatePartition wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<Type>Primary</Type>
|
||||||
|
<Extend>true</Extend>
|
||||||
|
</CreatePartition>
|
||||||
|
</CreatePartitions>
|
||||||
|
<ModifyPartitions>
|
||||||
|
<ModifyPartition wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<PartitionID>1</PartitionID>
|
||||||
|
<Format>FAT32</Format>
|
||||||
|
<Label>EFI</Label>
|
||||||
|
</ModifyPartition>
|
||||||
|
<ModifyPartition wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<PartitionID>3</PartitionID>
|
||||||
|
<Format>NTFS</Format>
|
||||||
|
<Label>Windows</Label>
|
||||||
|
<Letter>C</Letter>
|
||||||
|
</ModifyPartition>
|
||||||
|
</ModifyPartitions>
|
||||||
|
</Disk>
|
||||||
|
</DiskConfiguration>
|
||||||
|
|
||||||
|
<ImageInstall>
|
||||||
|
<OSImage>
|
||||||
|
<InstallTo>
|
||||||
|
<DiskID>0</DiskID>
|
||||||
|
<PartitionID>3</PartitionID>
|
||||||
|
</InstallTo>
|
||||||
|
<InstallFrom>
|
||||||
|
<MetaData wcm:action="add">
|
||||||
|
<Key>/IMAGE/INDEX</Key>
|
||||||
|
<Value>${image_index}</Value>
|
||||||
|
</MetaData>
|
||||||
|
</InstallFrom>
|
||||||
|
</OSImage>
|
||||||
|
</ImageInstall>
|
||||||
|
|
||||||
|
<UserData>
|
||||||
|
<AcceptEula>true</AcceptEula>
|
||||||
|
<ProductKey>
|
||||||
|
<Key>${product_key}</Key>
|
||||||
|
<WillShowUI>Never</WillShowUI>
|
||||||
|
</ProductKey>
|
||||||
|
</UserData>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<!-- offlineServicing: inject remaining VirtIO drivers into installed OS -->
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<settings pass="offlineServicing">
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-PnpCustomizationsNonWinPE"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<DriverPaths>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
|
||||||
|
<Path>${virtio_drive}:\vioscsi\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="2">
|
||||||
|
<Path>${virtio_drive}:\viostor\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="3">
|
||||||
|
<Path>${virtio_drive}:\NetKVM\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="4">
|
||||||
|
<Path>${virtio_drive}:\Balloon\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="5">
|
||||||
|
<Path>${virtio_drive}:\pvpanic\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="6">
|
||||||
|
<Path>${virtio_drive}:\qxldod\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="7">
|
||||||
|
<Path>${virtio_drive}:\vioserial\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="8">
|
||||||
|
<Path>${virtio_drive}:\vioinput\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
<PathAndCredentials wcm:action="add" wcm:keyValue="9">
|
||||||
|
<Path>${virtio_drive}:\viorng\2k22\amd64</Path>
|
||||||
|
</PathAndCredentials>
|
||||||
|
</DriverPaths>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<!-- specialize: machine-specific config -->
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<settings pass="specialize">
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-Shell-Setup"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<ComputerName>*</ComputerName>
|
||||||
|
<TimeZone>${timezone}</TimeZone>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-TerminalServices-LocalSessionManager"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<fDenyTSConnections>false</fDenyTSConnections>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-ServerManager-SvrMgrNc"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<!-- oobeSystem: first-login, admin account, drivers, WinRM -->
|
||||||
|
<!-- ===================================================================== -->
|
||||||
|
<settings pass="oobeSystem">
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-Shell-Setup"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
|
||||||
|
<AutoLogon>
|
||||||
|
<Password>
|
||||||
|
<Value>${admin_password}</Value>
|
||||||
|
<PlainText>true</PlainText>
|
||||||
|
</Password>
|
||||||
|
<Enabled>true</Enabled>
|
||||||
|
<Username>Administrator</Username>
|
||||||
|
</AutoLogon>
|
||||||
|
|
||||||
|
<UserAccounts>
|
||||||
|
<AdministratorPassword>
|
||||||
|
<Value>${admin_password}</Value>
|
||||||
|
<PlainText>true</PlainText>
|
||||||
|
</AdministratorPassword>
|
||||||
|
</UserAccounts>
|
||||||
|
|
||||||
|
<FirstLogonCommands>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>1</Order>
|
||||||
|
<CommandLine
|
||||||
|
>cmd /c "${virtio_drive}:\virtio-win-guest-tools.exe /install /norestart -q"</CommandLine>
|
||||||
|
<Description>Install VirtIO drivers and QEMU Guest Agent</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>2</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Set-ExecutionPolicy Bypass -Scope LocalMachine -Force"</CommandLine>
|
||||||
|
<Description>Set execution policy</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>3</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Get-NetConnectionProfile | Set-NetConnectionProfile -NetworkCategory Private"</CommandLine>
|
||||||
|
<Description>Set network to Private</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>4</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Get-ChildItem WSMan:\localhost\Listener | Remove-Item -Recurse -ErrorAction SilentlyContinue"</CommandLine>
|
||||||
|
<Description>Remove existing WinRM listeners</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>5</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "New-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{Address='*';Transport='HTTP'}"</CommandLine>
|
||||||
|
<Description>Create WinRM HTTP listener</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>6</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Set-Item WSMan:\localhost\Service\AllowUnencrypted -Value True"</CommandLine>
|
||||||
|
<Description>Allow unencrypted WinRM</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>7</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Set-Item WSMan:\localhost\Service\Auth\Basic -Value True"</CommandLine>
|
||||||
|
<Description>Allow basic auth</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>8</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Set-Item WSMan:\localhost\MaxEnvelopeSizekb -Value 8192"</CommandLine>
|
||||||
|
<Description>Increase max envelope size</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>9</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Set-Service WinRM -StartupType Automatic"</CommandLine>
|
||||||
|
<Description>Set WinRM auto-start</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>10</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "New-NetFirewallRule -DisplayName WinRM-HTTP -Direction Inbound -Action Allow -Protocol TCP -LocalPort 5985 -Profile Any"</CommandLine>
|
||||||
|
<Description>Open firewall port 5985</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>11</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Restart-Service WinRM -Force"</CommandLine>
|
||||||
|
<Description>Restart WinRM service</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>12</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0"</CommandLine>
|
||||||
|
<Description>Install OpenSSH Server</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>13</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "Set-Service sshd -StartupType Automatic; Start-Service sshd"</CommandLine>
|
||||||
|
<Description>Enable and start sshd</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>14</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "New-NetFirewallRule -DisplayName OpenSSH-Server -Direction Inbound -Action Allow -Protocol TCP -LocalPort 22 -Profile Any"</CommandLine>
|
||||||
|
<Description>Open firewall port 22</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
<SynchronousCommand wcm:action="add">
|
||||||
|
<Order>15</Order>
|
||||||
|
<CommandLine
|
||||||
|
>powershell -NoProfile -Command "$conf = 'C:\ProgramData\ssh\sshd_config'; (Get-Content $conf) -replace '#PubkeyAuthentication yes','PubkeyAuthentication yes' -replace 'Match Group administrators','#Match Group administrators' -replace ' AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys','# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys' | Set-Content $conf; Restart-Service sshd"</CommandLine>
|
||||||
|
<Description>Configure sshd for pubkey auth</Description>
|
||||||
|
</SynchronousCommand>
|
||||||
|
</FirstLogonCommands>
|
||||||
|
|
||||||
|
<OOBE>
|
||||||
|
<HideEULAPage>true</HideEULAPage>
|
||||||
|
<HideLocalAccountScreen>true</HideLocalAccountScreen>
|
||||||
|
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
|
||||||
|
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||||
|
<ProtectYourPC>3</ProtectYourPC>
|
||||||
|
</OOBE>
|
||||||
|
</component>
|
||||||
|
|
||||||
|
<component
|
||||||
|
name="Microsoft-Windows-International-Core"
|
||||||
|
processorArchitecture="amd64"
|
||||||
|
publicKeyToken="31bf3856ad364e35"
|
||||||
|
language="neutral"
|
||||||
|
versionScope="nonSxS"
|
||||||
|
>
|
||||||
|
<InputLocale>${locale}</InputLocale>
|
||||||
|
<SystemLocale>${locale}</SystemLocale>
|
||||||
|
<UILanguage>${locale}</UILanguage>
|
||||||
|
<UserLocale>${locale}</UserLocale>
|
||||||
|
</component>
|
||||||
|
</settings>
|
||||||
|
|
||||||
|
</unattend>
|
||||||
115
ws2022/main.pkr.hcl
Normal file
115
ws2022/main.pkr.hcl
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
packer {
|
||||||
|
required_plugins {
|
||||||
|
proxmox = {
|
||||||
|
version = "~> 1"
|
||||||
|
source = "github.com/hashicorp/proxmox"
|
||||||
|
}
|
||||||
|
windows-update = {
|
||||||
|
version = "0.17.3"
|
||||||
|
source = "github.com/rgl/windows-update"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Source: Proxmox VM definition
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
source "proxmox-iso" "ws2022" {
|
||||||
|
# Proxmox connection
|
||||||
|
proxmox_url = var.proxmox_url
|
||||||
|
username = var.proxmox_token_id
|
||||||
|
token = var.proxmox_token_secret
|
||||||
|
node = var.proxmox_node
|
||||||
|
insecure_skip_tls_verify = var.proxmox_skip_tls
|
||||||
|
|
||||||
|
# VM metadata
|
||||||
|
vm_name = var.vm_name
|
||||||
|
template_description = "Windows Server 2022 Datacenter - Cloudbase-Init - Built ${formatdate("YYYY-MM-DD", timestamp())}"
|
||||||
|
vm_id = var.vm_id
|
||||||
|
|
||||||
|
# Hardware
|
||||||
|
os = "win11"
|
||||||
|
memory = var.vm_memory
|
||||||
|
cores = var.vm_cores
|
||||||
|
cpu_type = "x86-64-v3"
|
||||||
|
machine = "pc-q35-10.1"
|
||||||
|
bios = "ovmf"
|
||||||
|
qemu_agent = true
|
||||||
|
|
||||||
|
efi_config {
|
||||||
|
efi_storage_pool = var.storage_pool
|
||||||
|
efi_type = "4m"
|
||||||
|
pre_enrolled_keys = true
|
||||||
|
}
|
||||||
|
|
||||||
|
scsi_controller = "virtio-scsi-single"
|
||||||
|
|
||||||
|
disks {
|
||||||
|
type = "scsi"
|
||||||
|
disk_size = var.disk_size
|
||||||
|
storage_pool = var.storage_pool
|
||||||
|
format = "raw"
|
||||||
|
}
|
||||||
|
|
||||||
|
network_adapters {
|
||||||
|
model = "virtio"
|
||||||
|
bridge = var.network_bridge
|
||||||
|
firewall = false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Windows Server 2022 ISO
|
||||||
|
iso_file = var.iso_file
|
||||||
|
|
||||||
|
# --- KEY: dynamically generated ISO with templated Autounattend.xml ---
|
||||||
|
additional_iso_files {
|
||||||
|
cd_content = {
|
||||||
|
"Autounattend.xml" = templatefile("answer_files/Autounattend.xml.pkrtpl", {
|
||||||
|
admin_password = var.admin_password
|
||||||
|
image_index = var.image_index
|
||||||
|
product_key = var.product_key
|
||||||
|
locale = var.locale
|
||||||
|
timezone = var.timezone
|
||||||
|
virtio_drive = var.virtio_drive_letter
|
||||||
|
})
|
||||||
|
}
|
||||||
|
cd_label = "OEMDRV"
|
||||||
|
iso_storage_pool = var.iso_storage_pool
|
||||||
|
unmount = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# VirtIO drivers ISO
|
||||||
|
additional_iso_files {
|
||||||
|
device = "sata1"
|
||||||
|
iso_file = var.virtio_iso
|
||||||
|
iso_storage_pool = var.iso_storage_pool
|
||||||
|
unmount = true
|
||||||
|
}
|
||||||
|
|
||||||
|
# WinRM communicator - password injected from variable
|
||||||
|
communicator = "winrm"
|
||||||
|
winrm_username = "Administrator"
|
||||||
|
winrm_password = var.admin_password
|
||||||
|
winrm_timeout = "90m"
|
||||||
|
winrm_insecure = true
|
||||||
|
winrm_use_ssl = false
|
||||||
|
|
||||||
|
boot_wait = "5s"
|
||||||
|
boot_command = ["<spacebar><spacebar><spacebar>"]
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
# Build: provisioning steps
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
build {
|
||||||
|
sources = ["source.proxmox-iso.ws2022"]
|
||||||
|
|
||||||
|
# Install and configure Cloudbase-Init
|
||||||
|
provisioner "powershell" {
|
||||||
|
script = "scripts/install-cloudbase-init.ps1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Sysprep with Cloudbase-Init's unattend
|
||||||
|
provisioner "powershell" {
|
||||||
|
script = "scripts/sysprep.ps1"
|
||||||
|
}
|
||||||
|
}
|
||||||
132
ws2022/scripts/install-cloudbase-init.ps1
Normal file
132
ws2022/scripts/install-cloudbase-init.ps1
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# install-cloudbase-init.ps1
|
||||||
|
# Packer provisioner: downloads, installs and configures Cloudbase-Init
|
||||||
|
# for Proxmox cloud-init (ConfigDrive metadata service).
|
||||||
|
|
||||||
|
$msiUrl = "https://cloudbase.it/downloads/CloudbaseInitSetup_Stable_x64.msi"
|
||||||
|
$msiPath = "C:\Windows\Temp\CloudbaseInitSetup.msi"
|
||||||
|
$cbDir = "C:\Program Files\Cloudbase Solutions\Cloudbase-Init"
|
||||||
|
|
||||||
|
# ---- Download ----
|
||||||
|
Write-Host "Downloading Cloudbase-Init..."
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
|
|
||||||
|
$retries = 3
|
||||||
|
for ($i = 1; $i -le $retries; $i++) {
|
||||||
|
try {
|
||||||
|
Invoke-WebRequest -Uri $msiUrl -OutFile $msiPath -UseBasicParsing
|
||||||
|
break
|
||||||
|
} catch {
|
||||||
|
Write-Host "Download attempt $i failed: $_"
|
||||||
|
if ($i -eq $retries) { throw "Failed to download Cloudbase-Init after $retries attempts" }
|
||||||
|
Start-Sleep -Seconds 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Unblock-File -Path $msiPath
|
||||||
|
|
||||||
|
# ---- Install (silent, Local System account) ----
|
||||||
|
Write-Host "Installing Cloudbase-Init..."
|
||||||
|
$proc = Start-Process msiexec.exe -ArgumentList "/i `"$msiPath`" /qn /norestart /l*v C:\Windows\Temp\cloudbase-install.log RUN_SERVICE_AS_LOCAL_SYSTEM=1" -Wait -PassThru
|
||||||
|
|
||||||
|
Write-Host "MSI exit code: $($proc.ExitCode)"
|
||||||
|
if ($proc.ExitCode -ne 0) {
|
||||||
|
# Dump the MSI log on failure
|
||||||
|
if (Test-Path "C:\Windows\Temp\cloudbase-install.log") {
|
||||||
|
Get-Content "C:\Windows\Temp\cloudbase-install.log" | Select-Object -Last 50
|
||||||
|
}
|
||||||
|
throw "Cloudbase-Init MSI install failed with exit code $($proc.ExitCode)"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait for MSI to finish writing files
|
||||||
|
Start-Sleep -Seconds 15
|
||||||
|
|
||||||
|
# ---- Verify installation ----
|
||||||
|
Write-Host "Verifying Cloudbase-Init installation..."
|
||||||
|
|
||||||
|
# Check the service exists
|
||||||
|
$svc = Get-Service -Name "cloudbase-init" -ErrorAction SilentlyContinue
|
||||||
|
if (-not $svc) {
|
||||||
|
Write-Host "Service not found. Listing directory..."
|
||||||
|
if (Test-Path $cbDir) {
|
||||||
|
Get-ChildItem $cbDir -Recurse -Depth 2 | Select-Object FullName
|
||||||
|
} else {
|
||||||
|
Write-Host "$cbDir does not exist!"
|
||||||
|
}
|
||||||
|
throw "Cloudbase-Init service not found after install!"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Cloudbase-Init installed. Service status: $($svc.Status)"
|
||||||
|
Write-Host "Cloudbase-Init installed successfully."
|
||||||
|
|
||||||
|
# ---- cloudbase-init.conf (main service - runs on normal boot after sysprep) ----
|
||||||
|
$mainConf = @"
|
||||||
|
[DEFAULT]
|
||||||
|
username=Administrator
|
||||||
|
groups=Administrators
|
||||||
|
inject_user_password=true
|
||||||
|
config_drive_raw_hhd=true
|
||||||
|
config_drive_cdrom=true
|
||||||
|
config_drive_vfat=true
|
||||||
|
bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
|
||||||
|
mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
|
||||||
|
verbose=true
|
||||||
|
debug=true
|
||||||
|
log_dir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
|
||||||
|
log_file=cloudbase-init.log
|
||||||
|
default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
|
||||||
|
logging_serial_port_settings=
|
||||||
|
first_logon_behaviour=no
|
||||||
|
mtu_use_dhcp_config=true
|
||||||
|
ntp_use_dhcp_config=true
|
||||||
|
local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
|
||||||
|
check_latest_version=false
|
||||||
|
plugins=cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,
|
||||||
|
cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin,
|
||||||
|
cloudbaseinit.plugins.common.setuserpassword.SetUserPasswordPlugin,
|
||||||
|
cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin
|
||||||
|
metadata_services=cloudbaseinit.metadata.services.configdrive.ConfigDriveService
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Host "Writing cloudbase-init.conf..."
|
||||||
|
Set-Content -Path "$cbDir\conf\cloudbase-init.conf" -Value $mainConf -Encoding ASCII
|
||||||
|
|
||||||
|
# ---- cloudbase-init-unattend.conf (specialize phase on first boot after sysprep) ----
|
||||||
|
$unattendConf = @"
|
||||||
|
[DEFAULT]
|
||||||
|
username=Administrator
|
||||||
|
groups=Administrators
|
||||||
|
inject_user_password=false
|
||||||
|
config_drive_raw_hhd=true
|
||||||
|
config_drive_cdrom=true
|
||||||
|
config_drive_vfat=true
|
||||||
|
bsdtar_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\bsdtar.exe
|
||||||
|
mtools_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\bin\
|
||||||
|
verbose=true
|
||||||
|
debug=true
|
||||||
|
log_dir=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\log\
|
||||||
|
log_file=cloudbase-init-unattend.log
|
||||||
|
default_log_levels=comtypes=INFO,suds=INFO,iso8601=WARN,requests=WARN
|
||||||
|
logging_serial_port_settings=
|
||||||
|
mtu_use_dhcp_config=false
|
||||||
|
ntp_use_dhcp_config=false
|
||||||
|
first_logon_behaviour=no
|
||||||
|
local_scripts_path=C:\Program Files\Cloudbase Solutions\Cloudbase-Init\LocalScripts\
|
||||||
|
check_latest_version=false
|
||||||
|
plugins=cloudbaseinit.plugins.common.sethostname.SetHostNamePlugin,
|
||||||
|
cloudbaseinit.plugins.common.networkconfig.NetworkConfigPlugin,
|
||||||
|
cloudbaseinit.plugins.windows.extendvolumes.ExtendVolumesPlugin
|
||||||
|
metadata_services=cloudbaseinit.metadata.services.configdrive.ConfigDriveService
|
||||||
|
allow_reboot=true
|
||||||
|
stop_service_on_exit=false
|
||||||
|
"@
|
||||||
|
|
||||||
|
Write-Host "Writing cloudbase-init-unattend.conf..."
|
||||||
|
Set-Content -Path "$cbDir\conf\cloudbase-init-unattend.conf" -Value $unattendConf -Encoding ASCII
|
||||||
|
|
||||||
|
# ---- Service configuration ----
|
||||||
|
Write-Host "Configuring Cloudbase-Init service..."
|
||||||
|
Set-Service -Name "cloudbase-init" -StartupType Automatic
|
||||||
|
|
||||||
|
# ---- Cleanup ----
|
||||||
|
Remove-Item $msiPath -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
Write-Host "=== Cloudbase-Init setup complete ==="
|
||||||
24
ws2022/scripts/sysprep.ps1
Normal file
24
ws2022/scripts/sysprep.ps1
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
$cbUnattend = "C:\Program Files\Cloudbase Solutions\Cloudbase-Init\conf\Unattend.xml"
|
||||||
|
|
||||||
|
if (-not (Test-Path $cbUnattend)) {
|
||||||
|
throw "Cloudbase-Init Unattend.xml not found at: $cbUnattend"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Removing Packer WinRM firewall rule..."
|
||||||
|
Remove-NetFirewallRule -DisplayName "WinRM HTTP" -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
Write-Host "Cleaning temp files..."
|
||||||
|
Remove-Item -Path "C:\Windows\Temp\*" -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
|
||||||
|
Write-Host "Enabling built-in Administrator account..."
|
||||||
|
net user Administrator /active:yes
|
||||||
|
net user Administrator /logonpasswordchg:no
|
||||||
|
|
||||||
|
Write-Host "Running Sysprep /generalize /oobe /shutdown..."
|
||||||
|
& "$env:SystemRoot\System32\Sysprep\Sysprep.exe" `
|
||||||
|
/generalize `
|
||||||
|
/oobe `
|
||||||
|
/shutdown `
|
||||||
|
/unattend:"$cbUnattend"
|
||||||
116
ws2022/variables.pkr.hcl
Normal file
116
ws2022/variables.pkr.hcl
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
variable "proxmox_url" {
|
||||||
|
type = string
|
||||||
|
description = "Proxmox API URL (e.g. https://pve.example.com:8006/api2/json)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_token_id" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
description = "Proxmox API token ID (e.g. user@pam!packer)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_token_secret" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
description = "Proxmox API token secret"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_node" {
|
||||||
|
type = string
|
||||||
|
description = "Proxmox node name to build on"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "proxmox_skip_tls" {
|
||||||
|
type = bool
|
||||||
|
default = true
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_name" {
|
||||||
|
type = string
|
||||||
|
default = "ws2022dc-template"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_id" {
|
||||||
|
type = number
|
||||||
|
default = 1002
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_memory" {
|
||||||
|
type = number
|
||||||
|
default = 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_cores" {
|
||||||
|
type = number
|
||||||
|
default = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "disk_size" {
|
||||||
|
type = string
|
||||||
|
default = "60G"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "network_bridge" {
|
||||||
|
type = string
|
||||||
|
default = "vmbr0"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "storage_pool" {
|
||||||
|
type = string
|
||||||
|
default = "local-lvm"
|
||||||
|
description = "Proxmox storage pool for VM disks and EFI"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "iso_storage_pool" {
|
||||||
|
type = string
|
||||||
|
default = "local"
|
||||||
|
description = "Proxmox storage pool where ISOs live and generated ISOs are placed"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "iso_file" {
|
||||||
|
type = string
|
||||||
|
description = "Path to Windows Server 2022 ISO in Proxmox (e.g. local:iso/WindowsServer2022.iso)"
|
||||||
|
default = "local-btrfs:iso/en-us_windows_server_2022_updated_july_2023_x64_dvd_541692c3.iso"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "virtio_iso" {
|
||||||
|
type = string
|
||||||
|
default = "local-btrfs:iso/virtio-win-0.1.285.iso"
|
||||||
|
description = "Path to VirtIO drivers ISO in Proxmox"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "virtio_drive_letter" {
|
||||||
|
type = string
|
||||||
|
default = "E"
|
||||||
|
description = "Drive letter where the VirtIO ISO is mounted inside Windows"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "admin_password" {
|
||||||
|
type = string
|
||||||
|
sensitive = true
|
||||||
|
description = "Administrator password used during build (will be cleared by sysprep)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "image_index" {
|
||||||
|
type = string
|
||||||
|
default = "4"
|
||||||
|
description = "Windows image index from eval ISO: 1=Std Core, 2=Std Desktop, 3=DC Core, 4=DC Desktop (verify with dism /Get-ImageInfo)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "product_key" {
|
||||||
|
type = string
|
||||||
|
default = "WX4NM-KYWYW-QJJR4-XV3QB-6VM33"
|
||||||
|
description = "KMS GVLK for Windows Server 2022 Datacenter"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "locale" {
|
||||||
|
type = string
|
||||||
|
default = "en-US"
|
||||||
|
description = "Windows locale for UI, input, system (e.g. en-US, hr-HR)"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "timezone" {
|
||||||
|
type = string
|
||||||
|
default = "Central European Standard Time"
|
||||||
|
description = "Windows timezone name"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user