Skip to content

Commit

Permalink
Windows Support Improvements (#277)
Browse files Browse the repository at this point in the history
- Added Support for Windows Server 2025 ISO and VHDX builds
- Added Support for Windows 11 ISO builds
- Autounattend.xml Template file clean-ups
- Added a new timeout parameter
  • Loading branch information
alanbach authored Nov 18, 2024
1 parent 26b6355 commit 8639ee3
Show file tree
Hide file tree
Showing 9 changed files with 255 additions and 51 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ Read more about how [custom images](https://maas.io/docs/how-to-customise-images
| Windows 2016 | Beta | >= 3.3 |
| Windows 2019 | Beta | >= 3.3 |
| Windows 2022 | Beta | >= 3.3 |
| Windows 2025 | Beta | >= 3.3 |
| Windows 10 | Beta | >= 3.3 |
| Windows 11 | Beta | >= 3.3 |

### Maturity level

Expand Down
54 changes: 47 additions & 7 deletions windows/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,32 @@ PACKER ?= packer
PACKER_LOG ?= 0
export PACKER_LOG

ISO ?=
ISO ?=
VHDX ?=
VERSION ?= 2022
BOOT ?= uefi
HEADLESS ?= false
FORMAT ?= ISO
TIMEOUT ?= 1h

ifeq ($(strip $(VERSION)),10)
TYPE = Windows
EDIT ?= PRO
else ifeq ($(strip $(VERSION)),11)
TYPE = Windows
EDIT ?= PRO
USE_TPM ?= yes
else ifeq ($(strip $(VERSION)),2025)
TYPE = Windows Server
EDIT ?= SERVERSTANDARD
else
TYPE = Windows Server
EDIT ?= SERVERSTANDARD
endif

ifneq ($(strip $(VHDX)),)
FORMAT ?= VHDX
endif

ifeq ($(wildcard /usr/share/OVMF/OVMF_CODE.fd),)
OVMF_SFX ?= _4M
else
Expand All @@ -32,12 +42,12 @@ endif

all: windows

$(eval $(call check_packages_deps,cloud-image-utils ovmf,cloud-image-utils ovmf))
$(eval $(call check_packages_deps,cloud-image-utils,genisoimage,swtpm ovmf,cloud-image-utils ovmf,genisoimage,swtpm))

OVMF_VARS.fd: /usr/share/OVMF/OVMF_VARS*.fd
OVMF_VARS.fd: /usr/share/OVMF/OVMF_VARS*.ms.fd
cp -v $< $@

http/Autounattend.xml: http/Autounattend.xml.${BOOT}.template
http/Autounattend.xml: http/Autounattend.xml.${FORMAT}.template
sed s#@VERSION@#"${TYPE} ${VERSION} ${EDIT}"#g $< > $@
ifneq ($(strip $(PKEY)),)
sed -i s#@PKEY@#${PKEY}#g $@
Expand All @@ -55,11 +65,41 @@ extra_drivers:
.INTERMEDIATE: extra_drivers http/Autounattend.xml

windows: check-deps clean extra_drivers http/Autounattend.xml OVMF_VARS.fd
ifeq ($(strip $(VERSION)),11)
mkdir -p /tmp/swtpm; \
swtpm socket --daemon --tpm2 --tpmstate dir=/tmp/swtpm --ctrl type=unixio,path=/tmp/swtpm/swtpm-sock --log level=10
endif
ifneq ($(strip $(VHDX)),)
qemu-img convert -p -O raw ${VHDX} windows_builder.img; \
scripts/setup-nbd windows_builder.img; \
TMP_DIR=$$(mktemp -d /tmp/packer-maas-XXXX); \
nbd=$$(cat /tmp/nbd.lock); \
pnum=$$(lsblk -l $${nbd} | grep -c part); \
echo 'Adding unattend.xml to image...'; \
mount -t ntfs $${nbd}p$${pnum} $${TMP_DIR}; \
mkdir -pv $${TMP_DIR}/Windows/Panther/; \
cp -v ./http/Autounattend.xml $${TMP_DIR}/Windows/Panther/unattend.xml; \
sync -f $${TMP_DIR}/Windows/Panther/; \
umount $${TMP_DIR}; \
qemu-nbd -d $${nbd}; \
rmdir $${TMP_DIR};
${PACKER} init . && ${PACKER} build -var iso_path=windows_builder.img \
-var headless=${HEADLESS} \
-var ovmf_suffix=${OVMF_SFX} \
-var timeout=${TIMEOUT} \
-var is_vhdx=true \
-var disk_size=64G \
windows.pkr.hcl
else
${PACKER} init . && ${PACKER} build -var iso_path=${ISO} \
-var headless=${HEADLESS} \
-var ovmf_suffix=${OVMF_SFX} \
-var is_vhdx=false \
-var timeout=${TIMEOUT} \
-var use_tpm=${USE_TPM} \
windows.pkr.hcl
endif

clean:
${RM} -rf output-* windows.tar.gz http/Autounattend.xml \
drivers.iso OVMF_VARS.fd
${RM} -rf output-* windows.dd.gz http/Autounattend.xml \
drivers.iso windows_builder.img OVMF_VARS.fd
34 changes: 27 additions & 7 deletions windows/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The Packer templates in this directory creates Windows Server images for use wit
* ovmf
* cloud-image-utils
* [Packer](https://www.packer.io/intro/getting-started/install.html), v1.7.0 or newer
* Ubuntu 22.04+ is required to build Windows 11 images (swtpm package)


## Requirements (to deploy the image)
Expand All @@ -26,30 +27,35 @@ The Packer templates in this directory creates Windows Server images for use wit
This process has been build and deployment tested with the following versions of
Microsoft Windows:

* Windows Server 2025
* Windows Server 2022
* Windows Server 2019
* Windows Server 2016
* Windows 10 Pro 22H2
* Windows 10 PRO+
* Windows 11 PRO+


## Known Issues
## Known Limitations

* The current process builds UEFI compatible images only.


## windows.pkr.hcl Template

This template builds a dd.tgz MAAS image from an official Microsoft Windows ISO.
This template builds a dd.tgz MAAS image from an official Microsoft Windows ISO/VHDX.
This process also installs the latest VirtIO drivers as well as Cloudbase-init.


## Obtaining Microsoft Windows ISO images

You can obtains Microsoft Windows Evaluation ISO images from the following links:
You can obtains Microsoft Windows Evaluation ISO/VHDX images from the following links:

* [Windows Server 2025](https://www.microsoft.com/en-us/evalcenter/download-windows-server-2025)
* [Windows Server 2022](https://www.microsoft.com/en-us/evalcenter/download-windows-server-2022)
* [Windows Server 2019](https://www.microsoft.com/en-us/evalcenter/download-windows-server-2019)
* [Windows Server 2016](https://www.microsoft.com/en-us/evalcenter/download-windows-server-2016)
* [Windows 10 Enterprise](https://www.microsoft.com/en-us/evalcenter/download-windows-10-enterprise)
* [Windows 11 Enterprise](https://www.microsoft.com/en-us/evalcenter/download-windows-11-enterprise)


### Building the image
Expand All @@ -61,6 +67,12 @@ customization:
sudo make windows ISO=<path-to-iso> VERSION=<windows-version>
```

Example:

```shell
sudo make ISO=/mnt/iso/Windows_Server_2025_SERVER_EVAL_x64FRE_en-us.iso VERSION=2025
```

### Makefile Parameters

#### BOOT
Expand All @@ -80,7 +92,7 @@ Whether VNC viewer should not be launched. Default is set to false.

#### ISO

Path to Microsoft Windows ISO used to build the image.
Path to Microsoft Windows ISO image used to build the image.

#### PACKER_LOG

Expand All @@ -98,10 +110,18 @@ the build time depending on the type of ISO being used. Evaluation series ISO
images usually do not require a product key to proceed, however this is not
true with Enterprise and Retail ISO images.

#### TIMEOUT

Defaults to 1h. Supports variables in h (hour) and m (Minutes).

#### VHDX

Path to Microsoft Windows VHDX image used to build the image.

#### VERSION

Specify the Microsoft Windows Version. Example inputs include: 2022, 2019, 2016
and 10.
Specify the Microsoft Windows Version. Example inputs include: 2025, 2022, 2019, 2016, 10
and 11.


## Uploading images to MAAS
Expand Down
3 changes: 0 additions & 3 deletions windows/TODO.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
## To be implemented (TODO List)

* Complete the support for build-time driver injection.
* Add support for BIOS based deployments.
* Add support for Windows 11 which requires TPM 2.0.
* Migrate scripts/setup-nbd to use fuse.

Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@
<ImageInstall>
<OSImage>
<InstallTo>

<PartitionID>3</PartitionID>
<DiskID>0</DiskID>

</InstallTo>
<InstallToAvailablePartition>false</InstallToAvailablePartition>
<WillShowUI>OnError</WillShowUI>
Expand All @@ -66,7 +64,7 @@
<AcceptEula>true</AcceptEula>
</UserData>
</component>
<component name="Microsoft-Windows-International-Core-WinPE" 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">
<component name="Microsoft-Windows-International-Core-WinPE" 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">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
Expand All @@ -92,11 +90,6 @@
<ProtectYourPC>3</ProtectYourPC>
<NetworkLocation>Work</NetworkLocation>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<!-- Comment the following two options on Windows Vista / 7 and Windows Server 2008 / 2008 R2 -->
<!--
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
-->
</OOBE>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
Expand Down
109 changes: 109 additions & 0 deletions windows/http/Autounattend.xml.VHDX.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend">
<settings pass="windowsPE">
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<UserData>
<!--<ProductKey>
<Key>@PKEY@</Key>
<WillShowUI>Never</WillShowUI>
</ProductKey>-->
<AcceptEula>true</AcceptEula>
</UserData>
</component>
<component name="Microsoft-Windows-International-Core-WinPE" 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">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<InputLocale>en-US</InputLocale>
<UILanguage>en-US</UILanguage>
<SystemLocale>en-US</SystemLocale>
<UserLocale>en-US</UserLocale>
</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 name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<VisualEffects>
<FontSmoothing>ClearType</FontSmoothing>
</VisualEffects>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<ProtectYourPC>3</ProtectYourPC>
<NetworkLocation>Work</NetworkLocation>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
</OOBE>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<CommandLine>%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell -NoLogo -NonInteractive -ExecutionPolicy RemoteSigned -Command A:\logon.ps1 </CommandLine>
<Order>1</Order>
</SynchronousCommand>
</FirstLogonCommands>
<UserAccounts>
<AdministratorPassword>
<Value>Passw0rd</Value>
<PlainText>true</PlainText>
</AdministratorPassword>
<!--<LocalAccounts>
<LocalAccount wcm:action="add">
<Password>
<Value>Passw0rd</Value>
<PlainText>true</PlainText>
</Password>
<Description>Packer Administrator</Description>
<DisplayName>defaultuser</DisplayName>
<Group>Administrators</Group>
<Name>defaultuser</Name>
</LocalAccount>
</LocalAccounts>-->
</UserAccounts>
<AutoLogon>
<Password>
<Value>Passw0rd</Value>
<PlainText>true</PlainText>
</Password>
<Enabled>true</Enabled>
<LogonCount>50</LogonCount>
<Username>Administrator</Username>
</AutoLogon>
<ComputerName>*</ComputerName>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<RunAsynchronous>
<RunAsynchronousCommand>
<Order>1</Order>
<Path>reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\OOBE" /v SetupDisplayedProductKey /t REG_DWORD /d 1 /f</Path>
<Description>Disable Product Key Pop-up During Setup</Description>
</RunAsynchronousCommand>
</RunAsynchronous>
</component>
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" 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">
<fDenyTSConnections>false</fDenyTSConnections>
</component>
<component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" 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">
<UserAuthentication>0</UserAuthentication>
</component>
<component name="Networking-MPSSVC-Svc" 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">
<FirewallGroups>
<FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop">
<Active>true</Active>
<Profile>all</Profile>
<Group>@FirewallAPI.dll,-28752</Group>
</FirewallGroup>
</FirewallGroups>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="NonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<TimeZone>UTC</TimeZone>
<ComputerName>*</ComputerName>
</component>
<component name="Microsoft-Windows-SQMApi" 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">
<CEIPEnabled>0</CEIPEnabled>
</component>
</settings>
</unattend>
2 changes: 1 addition & 1 deletion windows/http/logon.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ try

# Install virtio drivers
$Host.UI.RawUI.WindowTitle = "Installing Virtio Drivers..."
certutil -addstore "TrustedPublisher" A:/rh.cer
certutil -addstore "TrustedPublisher" A:\rh.cer
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win-gt-x64.msi" -Outfile "c:\virtio.msi"
Invoke-WebRequest "https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win-guest-tools.exe" -Outfile "c:\virtio.exe"
Expand Down
Loading

0 comments on commit 8639ee3

Please sign in to comment.