Creating a small footprint, base image Part 1 | VHDX from ISO

New-WindowsImage -size small | Test-Lab

One of the time consuming steps to deploying new VMs is the time spend managing Images and and applying patches. I’m not big on Golden images. I tend to use a fully patched VHDX or VMDK  and let DSC handle the configuration and software. This is not the fastest, and at scale you need to create more then one image based on what saves the most time.  (IIS, SQL, Exchange, etc…).

In this series, I’m going to go over how I create a a baseline image of 2012r2 with PowerShell. Also because Install-WindowsFeature has issues when the target VM has been patched, we are also going to create a fully patched WIM to use as -source.

Blogs in this Series

VHDX from ISO

First you need a 20112r2 ISO, at work you would get this from the Volume License Service center. Every time Microsoft releases a roll-up, they usually update the ISO file so it’s a good idea check every few months for an updated ISO. Now for a home lab, unless you have a personal MSDN, your going to need an ISO from another source.  I’m just going with the latest trial from the TechNet Evaluation Center. Don’t download the VHD. We are going to need both Core and GUI from the ISO. While we could get there from the VHD, It’s not the path I’m taking.

I’m saving the ISO in c:\ISO\ and renaming it Server2012R2.ISO

Now what I’m going to do is create two VHDX one core and one with a GUI. I could use the ISO to manually install but I want to limit my use of the mouse, (and screen shots are a pain to insert in the blog)

Once I have that downloaded I can mount it on My windows 8.1 hyper-v host that contains the Test Lab. The reason for this is I will need the VHDX on the host. The WMI file can be on any share accessible by the VM’s.

PS C:\> Mount-DiskImage -ImagePath c:\ISO\Server2012R2.ISO

This will mount it as it’s own drive. in my case I:

Next I’m going to need a way to extract the contents of Install.wim and create a properly formatted VHDX. Now many of the examples of this online are for Gen1 machines. I want Gen2. so I’m going to get a copy of Convert-WindowsImage.ps1
Unfortunately this is not a module but and advanced script.  I’m not going to go in-depth on how Convert-WindowsImage works. Check it’s help and open it up if your curious.

Unblock-File G:\temp\Convert-WindowsImage.ps1
G:\temp\Convert-WindowsImage.ps1 -SourcePath I:\sources\install.wim -VHDPath G:\temp\CoreFromIso.vhdx -SizeBytes 40gb -VHDType Dynamic -VHDFormat VHDX -VHDPartitionStyle GPT -Edition 3 -Verbose
Windows(R) Image to Virtual Hard Disk Converter for Windows(R) 8
 Copyright (C) Microsoft Corporation.  All rights reserved.
 Version 6.3.9600.7.amd64fre.fbl_core1_hyp_dev(mikekol).140217-3000 Release to Web
 VERBOSE: isUserAdmin? True
 VERBOSE: isWindows8? True
 VERBOSE: Temporary VHDX path is : c:\temp\a585fb17-2bfe-4db6-8440-034c561e53ce.vhdx
 INFO   : Image 3 selected (ServerDataCenterEvalCore)...
 INFO   : Creating sparse disk...
 INFO   : Attaching VHDX...
 INFO   : Disk initialized with GPT...
 INFO   : Disk partitioned with two Volumes...
 INFO   : System Volume formatted (with DiskPart)...
 INFO   : Boot Volume formatted (with Format-Volume)...
 INFO   : Access path (J:\) has been assigned to the System Volume...
 INFO   : Access path (K:\) has been assigned to the Boot Volume...
 INFO   : Applying image to VHDX. This could take a while...
 INFO   : Signing disk...
 INFO   : Image applied. Making image bootable...
 VERBOSE: Running bcdboot.exe K:\Windows /s J:\ /v /f UEFI
 VERBOSE: Return code was 0.
 INFO   : Drive is bootable. Cleaning up...
 INFO   : Closing VHDX...
 INFO   : Closing Windows image...
 INFO   : Done.
G:\temp\Convert-WindowsImage.ps1 -SourcePath G:\sources\install.wim -VHDPath G:\temp\GUIFromIso.vhdx -SizeBytes 40gb -VHDType Dynamic -VHDFormat VHDX -VHDPartitionStyle GPT -Edition 4 -Verbose
Windows(R) Image to Virtual Hard Disk Converter for Windows(R) 8
 Copyright (C) Microsoft Corporation.  All rights reserved.
 Version 6.3.9600.7.amd64fre.fbl_core1_hyp_dev(mikekol).140217-3000 Release to Web
 VERBOSE: isUserAdmin? True
 VERBOSE: isWindows8? True
 VERBOSE: Temporary VHDX path is : G:\temp\dd0ac2d0-b05c-461f-b071-d73b59522bb4.vhdx
 INFO   : Image 4 selected (ServerDataCenterEval)...
 INFO   : Creating sparse disk...
 INFO   : Attaching VHDX...
 INFO   : Disk initialized with GPT...
 INFO   : Disk partitioned with two Volumes...
 INFO   : System Volume formatted (with DiskPart)...
 INFO   : Boot Volume formatted (with Format-Volume)...
 INFO   : Access path (K:\) has been assigned to the System Volume...
 INFO   : Access path (L:\) has been assigned to the Boot Volume...
 INFO   : Applying image to VHDX. This could take a while...
 INFO   : Signing disk...
 INFO   : Image applied. Making image bootable...
 VERBOSE: Running bcdboot.exe L:\Windows /s K:\ /v /f UEFI
 VERBOSE: Return code was 0.
 INFO   : Drive is bootable. Cleaning up...
 INFO   : Closing VHDX...
 INFO   : Closing Windows image...
 INFO   : Done.
disMount-DiskImage -ImagePath c:\ISO\Server2012R2.ISO
dir
Directory: C:\temp
Mode                LastWriteTime     Length Name
 ----                -------------     ------ ----
 -a---         5/14/2015   3:16 PM     187332 Convert-WindowsImage.ps1
 -a---         5/14/2015   3:29 PM 5104467968 CoreFromIso.vhdx
 -a---         5/14/2015   3:42 PM 8157921280 GUIFromIso.vhdx

 We now have two VHDX files however they are still a little out of date, and we can still trim them up a bit.

I’m going to copy the VHDX files, just so we can see how the size changes on each step.

copy .\CoreFromIso.vhdx CorePatched.vhdx

copy .\GUIFromIso.vhdx GuiPatched.vhdx

Now we will create VM’s and attach the two drives.  I will also add the ISO to the GUI version as we need it for making sure all windows features are ‘Available”

new-vm -Name CorePatch -MemoryStartupBytes 1024MB -BootDevice VHD -VHDPath G:\temp\CorePatched.vhdx -Generation 2 -SwitchName TestLab
Name      State CPUUsage(%) MemoryAssigned(M) Uptime   Status
 ----      ----- ----------- ----------------- ------   ------
 CorePatch Off   0           0                 00:00:00 Operating normally
new-vm -Name GuiPatch -MemoryStartupBytes 1024MB -BootDevice VHD -VHDPath G:\temp\GuiPatched.vhdx -Generation 2 -SwitchName TestLab
Name     State CPUUsage(%) MemoryAssigned(M) Uptime   Status
 ----     ----- ----------- ----------------- ------   ------
 GuiPatch Off   0           0                 00:00:00 Operating normally
Add-VMDvdDrive -Path C:\ISO\Server2012R2.ISO -VMName guipatch

Start-VM *patch

vmconnect localhost corepatch
vmconnect localhost guipatch

Those last two command connect me to the servers.

Now I’m going to go on the assumption that you have experience setting up server and you can handle the Out of Box experience on your own.

In Part 2 we will cover Windows Updates with PowerShell, along with cleaning up unneeded files.

Leave a comment