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