Testing unattended windows installations

If you are creating unattended.xml files to use to perform automated installations of windows then you will at some point want to test it.  This is fine if the destination system has a keyboard and monitor but in my case the system I am targeting does not, a HP MediaSmart EX490.

The simplest way I found on Windows 8 to do the testing was to use the Hyper-V role.  Normally I prepare a USB stick with the Microsoft USB/DVD Download Tool and then copy the autounattend.xml file to the root of the USB disk.  However, during installation Windows will search for an autounattend.xml or unattend.xml on other removable devices.  Using this we can setup a Hyper-V VM with two DVD drives.  One with the installation media in the other with just the autounattend.xml

I found on the internet a PowerShell script, New-IsoFile that will create an ISO from a list of files.  Credit goes to Chris Woo and information can be found at http://gallery.technet.microsoft.com/scriptcenter/New-ISOFile-function-a8deeffd

Below is my PowerShell script that I use.  Basically it uses Chris’s New-IsoFile function to create an ISO with the autounattend.xml file in it.  It then creates a VM, attaches the Installation ISO (in this case Hyper-V Server) and the answer file ISO and starts the VM.

function New-IsoFile { <# .Synopsis Creates a new .iso file .Description The New-IsoFile cmdlet creates a new .iso file containing content from chosen folders .Example New-IsoFile "c:\tools","c:Downloads\utils" Description ----------- This command creates a .iso file in $env:temp folder (default location) that contains c:\tools and c:\downloads\utils folders. The folders themselves are added in the root of the .iso image. .Example dir c:\WinPE | New-IsoFile -Path c:\temp\WinPE.iso -BootFile etfsboot.com -Media DVDPLUSR -Title "WinPE" Description ----------- This command creates a bootable .iso file containing the content from c:\WinPE folder, but the folder itself isn't included. Boot file etfsboot.com can be found in Windows AIK. Refer to IMAPI_MEDIA_PHYSICAL_TYPE enumeration for possible media types: http://msdn.microsoft.com/en-us/library/windows/desktop/aa366217(v=vs.85).aspx .Notes NAME: New-IsoFile AUTHOR: Chris Wu LASTEDIT: 03/06/2012 14:06:16 #> Param ( [parameter(Position=0,Mandatory=$true,ValueFromPipeline=$true)]$Source, [parameter(Position=1)][string]$Path = "$($env:temp)\" + (Get-Date).ToString("yyyyMMdd-HHmmss.ffff") + ".iso", [string] $BootFile = $null, [string] $Media = "Disk", [string] $Title = (Get-Date).ToString("yyyyMMdd-HHmmss.ffff"), [switch] $Force )#End Param Begin { ($cp = new-object System.CodeDom.Compiler.CompilerParameters).CompilerOptions = "/unsafe" if (!("ISOFile" -as [type])) { Add-Type -CompilerParameters $cp -TypeDefinition @" public class ISOFile { public unsafe static void Create(string Path, object Stream, int BlockSize, int TotalBlocks) { int bytes = 0; byte[] buf = new byte[BlockSize]; System.IntPtr ptr = (System.IntPtr)(&bytes); System.IO.FileStream o = System.IO.File.OpenWrite(Path); System.Runtime.InteropServices.ComTypes.IStream i = Stream as System.Runtime.InteropServices.ComTypes.IStream; if (o == null) { return; } while (TotalBlocks-- > 0) { i.Read(buf, BlockSize, ptr); o.Write(buf, 0, bytes); } o.Flush(); o.Close(); } } "@ }#End If if ($BootFile -and (Test-Path $BootFile)) { ($Stream = New-Object -ComObject ADODB.Stream).Open() $Stream.Type = 1 # adFileTypeBinary $Stream.LoadFromFile((Get-Item $BootFile).Fullname) ($Boot = New-Object -ComObject IMAPI2FS.BootOptions).AssignBootImage($Stream) }#End If $MediaType = @{CDR=2; CDRW=3; DVDRAM=5; DVDPLUSR=6; DVDPLUSRW=7; ` DVDPLUSR_DUALLAYER=8; DVDDASHR=9; DVDDASHRW=10; DVDDASHR_DUALLAYER=11; ` DISK=12; DVDPLUSRW_DUALLAYER=13; BDR=18; BDRE=19 } if ($MediaType[$Media] -eq $null) { write-debug "Unsupported Media Type: $Media"; write-debug ("Choose one from: " + $MediaType.Keys); break } ($Image = new-object -com IMAPI2FS.MsftFileSystemImage -Property @{VolumeName=$Title}).ChooseImageDefaultsForMediaType($MediaType[$Media]) if ((Test-Path $Path) -and (!$Force)) { "File Exists $Path"; break } if (!($Target = New-Item -Path $Path -ItemType File -Force)) { "Cannot create file $Path"; break } } Process { switch ($Source) { { $_ -is [string] } { $Image.Root.AddTree((Get-Item $_).FullName, $true); continue } { $_ -is [IO.FileInfo] } { $Image.Root.AddTree($_.FullName, $true); continue } { $_ -is [IO.DirectoryInfo] } { $Image.Root.AddTree($_.FullName, $true); continue } }#End switch }#End Process End { if ($Boot) { $Image.BootImageOptions=$Boot } $Result = $Image.CreateResultImage() [ISOFile]::Create($Target.FullName,$Result.ImageStream,$Result.BlockSize,$Result.TotalBlocks) $Target }#End End }#End function New-IsoFile # Begin script by Albal to create New-VM based on autounattend.xml - # Assumes all required files are in, and will be written to <USER>\Downloads # Change the below parameters if needed $path = [Environment]::GetFolderPath("UserProfile") + "\Downloads" $name = "Hyper-V Server 2012" $switch = "vSwitch" # Don't change anything below this line - ignore the errors below, just in case you run the script again without having exited expectedly Stop-VM -Name $name -Force -TurnOff Remove-VM -Name $name -Force del -Force $path\auto.iso del -Force $path\hyper-v.vhd dir $path\autounattend.xml | New-IsoFile -Path $path\auto.iso -Media CDR -Title "Unattend" New-Vm -Name $name -SwitchName $switch Set-VMProcessor -VMName $name -Count 1 Set-VMMemory -VMName $name -StartupBytes 2147483648 New-VHD -Path $path\hyper-v.vhd -SizeBytes 21474836480 Add-VMHardDiskDrive -VMName $name -Path $path\hyper-v.vhd -ControllerType IDE -ControllerNumber 0 -ControllerLocation 0 Set-VMDvdDrive -VMName $name -Path $path\en_microsoft_hyper-v_server_2012_x64_dvd_915600.iso -ControllerNumber 1 -ControllerLocation 0 Add-VMDvdDrive -VMName $name -Path $path\auto.iso -ControllerNumber 1 -ControllerLocation 1 Start-VM -Name $name echo "When you press enter the Virtual Machine will be stopped and deleted" pause Stop-VM -Name $name -Force -TurnOff Remove-VM -Name $name -Force del $path\hyper-v.vhd del $path\auto.iso


Simply run the Script and Open the VM in Hyper-V Manager, you can then verify the automated install works and if not have an easier time of debugging the situation than if you were running on a headless system.


Unattended install of Microsoft Hyper-V Server 2012

Microsoft Hyper-V Server 2012 is a free version of Windows Server 2012 that only supports the Hyper-V role. You can use this to install on bare metal to give you a hyper visor that can support virtualisation. In this article I will be looking at how you prepare an image and configuration file (autounattend.xml) to target a server for a hands off installation.

Resources you will need

Download the ISO, install the DVD tool but when you come to install the ADK only install the Deployment Tools:


You will need to run the Windows System Image Manager:


First mount the ISO on a local drive or open it in another program to extract the install.wim file from the sources folder.  Save this file to your local hard disk.  From the File Menu select New Answer File… then choose Yes to Open a new Windows Image:


Select the Windows install.wim Image that you copied from the Sources folder earlier:


Then select yes to create the catalogue file.  This will take a few minutes.  At this point you could use the USB/DVD download tool to create your bootable USB drive. A 2GB USB Drive will do fine for this.

When the creation of the catalogue file has completed you will need to add a number of configuration options from the Windows Image section in the bottom left of the Windows System Image Manager window to the Answer File.  You do this by opening the Components Tree and right-clicking on a Component with the mouse and selecting the appropriate phase to add it to.  You will then see the Answer File populate with the Configuration Option that you can edit later.  I will details the Configuration Options you need to add to your answer file to enable an unattended install of Windows Hyper-V Server 2012.

Add the following to 1 windowsPE:

  • amd64_Microsoft-Windows-International-Core-WinPE
  • amd64_Microsoft-Windows-Setup

Add the following to 4 specialize:

  • amd64_Microsoft-Windows-Shell-Setup
  • amd64_Microsoft-Windows-TerminalServices-LocalSessionManager
  • amd64_Microsoft-Windows-TerminalServices-RDP-WinStationExtensions
  • amd64_Microsoft-Windows-UnattendedJoin

Add the following to 7 oobe System:

  • amd64_Microsoft-Windows-Shell-Setup


Remove any items from the tree that you may have that are not shown above.  They will not be needed.

Go back to the top of the Tree and Select amd64_Microsoft-Windows-International-Core-WinPE.  For Input Local, SystemLocale, UILanguage, UILanguageFallback and UserLocale enter en-US


Select SetupUILanguage and set UI Language to en-US and WillShowUI to OnError


Select amd64_Microsoft-Windows-Setup, set EnableFirewall to False and EnableNetwork to True


Then select DiskConfiguration right click and select Insert New Disk. Set the DiskID to 0 and set WillWipeDisk to True


Right click on CreatePartitions and select Insert New CreatePartition on this set Order to 1, Size to 100 and Type to Primary


Do the same again but set the Extend to true, Order to 2 and Type to Primary


Move down to ModifyPartitions right click and select Insert New ModifyPartition, set Active to True, Format to NTFS, Label to Boot, Order to 1 and PartitionID to 1


Do the same again but don’t set Active,set Label to System, Order to 2 and PartitionID to 2


Select Image install right click and select Insert New OSImage. Set InstallToAvailablePartition to False and WillShowUI to OnError.  Select InstallFrom, right click and select Insert New MetaData.  Set the Key to /IMAGE/NAME and set Value to Hyper-V Server 2012 SERVERHYPERCORE. Remove Credentials


Select InstallTo and set DiskID to 0 and PartitionID to 2


Select UserData and set AcceptEula to True, FullName to User and Organization to Company


Select amd64_Microsoft-Windows-Shell-Setup, set ComputerName to HYPER-V-01, set RegisteredOwner to User and set TimeZone to UTC


Select amd64_Microsoft-Windows-TerminalServices-LocalSessionManager and set fDenyTSConnections to False


Select amd64_Microsoft-Windows-TerminalServices-RDP-WinStationExtensions, set SecurityLayer to 1 and UserAuthentication to 0


Select amd64_Microsoft-Windows-UnattendedJoin and then Identification, in this case we are setting to join a Workgroup so set JoinWorkgroup to WORKGROUP


Navigate to amd64_Microsoft-Windows-Shell-Setup and set RegisteredOrganization to Company, RegisteredOwner to User and TimeZone to UTC


Select AdministratorPassword and for Value type in the password you want to use, in clear text. Later WSIM will encrypt the password.  Don’t forget it.


From the Tools menu select Validate Answer File and in the message windows verify that No warnings or errors are shown.  From the File menu select Save As… and use the filename autounattend.xml to save the file to your local disk.  If you are going to boot the system from USB and you are confident that it will work then you can copy the XML file to your USB stick once you have prepared the USB stick using the Microsoft USB/DVD Download tool.

In my next article I will show you how to verify your unattended install in Hyper-V.  This is very useful for proving your answer file where it will be used on a headless system.

Linux Integration Service for Hyper-V Server 2012 / Windows 8

It’s not so easy to find but Microsoft have released the Linux Integration Services ISO for Windows Server 2012 and Windows 8. It also supports older instances of Hyper-V


•Driver support: Linux Integration Services supports the network controller and the IDE and SCSI storage controllers that were developed specifically for Hyper-V.

•Fastpath Boot Support for Hyper-V: Boot devices now take advantage of the block Virtualization Service Client (VSC) to provide enhanced performance.

•Time Keeping: The clock inside the virtual machine will remain accurate by synchronizing to the clock on the virtualization server via Timesync service, and with the help of the pluggable time source device.

•Integrated Shutdown: Virtual machines running Linux can be shut down from either Hyper-V Manager or System Center Virtual Machine Manager by using the “Shut down” command.

•Symmetric Multi-Processing (SMP) Support: Supported Linux distributions can use multiple virtual processors per virtual machine. The actual number of virtual processors that can be allocated to a virtual machine is only limited by the underlying hypervisor.

•Heartbeat: This feature allows the virtualization server to detect whether the virtual machine is running and responsive.

•KVP (Key Value Pair) Exchange: Information about the running Linux virtual machine can be obtained by using the Key Value Pair exchange functionality on the Windows Server 2008 virtualization server.

•Integrated Mouse Support: Linux Integration Services provides full mouse support for Linux guest virtual machines.

•Live Migration: Linux virtual machines can undergo live migration for load balancing purposes.

•Jumbo Frames: Linux virtual machines can be configured to use Ethernet frames with more than 1500 bytes of payload.

•VLAN tagging and trunking: Administrators can attach single or multiple VLAN ids to synthetic network adapters.

System requirements

Supported operating systems: Windows 8 Pro, Windows Server 2008, Windows Server 2008 R2, Windows Server 2008 R2 SP1, Windows Server 2012