We get regularly a lot of requests about how to generate Windows OpenStack images, especially for KVM, where the proper VirtIO drivers need to be installed.
This article provides all the step required to build one, as we did for the official OpenStack Windows Server 2012 R2 Evaluation images
All the scripts are publicly available on Github.
For people familiar with Linux unattended deployment solutions like kickstart or preseed files, Windows has a roughly similar model based on XML files which can be automatically generated with a freely available tool currently called Windows Assessment and Deployment Kit (ADK in short). The ADK is not necessary if you’re fine with tweaking XML files manually as we usually do.
Kickstart and Preseed files in Linux provide a “post” script where you can do some more advanced provisioning by running your own scripts. That’s also what we do here. The difference is that we split the work in 3 specific areas:
- SynchronousCommands during the Specialize step. This is the earliest moment in which we can run some custom actions. Scripts will be executed with the SYSTEM credentials and won’t be able to access some OS features that are not yet available, for example WMI. This is the best place where to place your script, especially if you expect a reboot to load your features.
- SynchronousCommands during the first logon. These commands get executed when the setup is basically done with the Administrator’s credentials (or whatever is specified in the XML file), just before the user can log in. As a comparison, this is the closest thing to a “post” script in a Kickstart file.
- AsysncronousCommands during logon. These commands are executed after the setup and are really useful if you need to execute work that requires an unspecified number of additional reboots. We use it mainly to execute Windows updates.
To make things simpler, during each of the above steps we download and execute a Powershell script from the Github repository instead of adding every single action that we want to run into the XML file. This way we have a lot more flexibility and troubleshooting issues while writing those scripts becomes a cakewalk, especially using virtual machine snapshots.
Here are the actions that are performed in detail:
- The most important feature: setting the Cloudbase Solutions wallpaper. 🙂
- Enabling ping response in the firewall (Note: RDP access is enabled in the XML file).
- Downloading the FirstLogon script.
- Detecting what platform we are running on (KVM, Hyper-V, ESXi, etc). This requires WMI and is the reason why this and the next step are not executed during the Specialize phase.
- Installing the relevant platform drivers and tools: VirtIO drivers on KVM and VMWare tools on ESXi. Nothing is needed on Hyper-V, as the relevant tools are already included starting with Windows Server 2008. Note: the VirtIO drivers are unsigned, so we use a trick to get the job done in a fully unattended way. 😉
Important note: The Fedora VirtIO drivers version 0.1-65 generate a blue screen when you attach a volume. Use the stable version instead.
- Downloading the logon script.
- Installing PSWindowsUpdate, a Powershell module to handle, well, Windows Updates.
- Installing the updates. At the end of each updates round a reboot is performed if needed and after reboot the same step is repeated until the system is up to date. Please note that this might take a while, mostly depending on your Internet connection speed.
- Downloading and installing the latest Cloudbase-Init version.
- Finally running Sysprep, using Cloudbase-Init’s Unattended.xml and rebooting.
All you have to do to prepare an image, is to start a VM with the Autounattend.xml file on a virtual floppy, the Windows Server ISO connected on the first DVDRom drive and the optional platform tools (VirtIO drivers, VMWare tools, etc) on the second DVDRom drive.
When the image is done, it will shut down automatically, ready to be put in Glance.
Fairly easy, no?
How to automate the image creation on KVM
if [ ! -f "$KVM" ]; then
qemu-img create -f qcow2 -o preallocation=metadata $IMAGE 16G
$KVM -m 2048 -smp 2 -cdrom $ISO -drive file=$VIRTIO_ISO,index=3,media=cdrom -fda $FLOPPY $IMAGE \
-boot d -vga std -k en-us -vnc :1
Note: don’t forget to open the VNC port on the hypervisor’s firewall if you want to check of things are going (5901 in the example). It’s very important not to interact with the OS while the scripts run, but it’s a great way to see how things progress.
How to automate the image creation on Hyper-V
$vmname = "OpenStack WS 2012 R2 Standard Evaluation"
# Set the extension to VHD instead of VHDX only if you plan to deploy
# this image on Grizzly or on Windows / Hyper-V Server 2008 R2
$vhdpath = "C:\VM\windows-server-2012-r2.vhdx"
$isoPath = "C:\your\path\9600.16384.WINBLUE_RTM.130821-1623_X64FRE_SERVER_EVAL_EN-US-IRM_SSS_X64FREE_EN-US_DV5.ISO"
$floppyPath = "C:\your\path\Autounattend.vfd"
# Set the vswitch accordingly with your configuration
$vmSwitch = "external"
New-VHD $vhdpath -Dynamic -SizeBytes (16 * 1024 * 1024 * 1024)
$vm = New-VM $vmname -MemoryStartupBytes (2048 * 1024 *1024)
$vm | Set-VM -ProcessorCount 2
$vm.NetworkAdapters | Connect-VMNetworkAdapter -SwitchName $vmSwitch
$vm | Add-VMHardDiskDrive -ControllerType IDE -Path $vhdpath
$vm | Add-VMDvdDrive -Path $isopath
$vm | Set-VMFloppyDiskDrive -Path $floppyPath
$vm | Start-Vm
Check the README file of the project for updates, we’re definitely going to add more hypervisor options!