Creating a small footprint, base image Part 4 | Bringing it all together with automation

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

Get-Script | Set-Automation

This took a little longer than I had expected. However I’m satisfied with the results if not the quality of my code.

I shortened up the process in Part1 by pointing Convert-WindowsImage.ps1 at the ISO directly. And I added some code deal with working folder and cleaning files we dont need.

The basic process is as follows

  1. Create the VHDX from ISO
  2. Insert three files
    1. unattend.xml : sets up a silent OOBE, autologin and start the first script.
    2. FirstRun.ps1 : handles any windows features and sets creates an ‘atstartup’ task to run the next script
    3. AtStarup.ps1 : Installs windows updates, and reboots, once none left shuts down the computer
  3. Create a VM
    1. If WIM, attach the ISO
    2. start VM
    3. wait for VM to shutdown
  4. If it’s the Template
    1. copy the VHDX
    2. replace AtStartup with a script that cleans up extra files and runs sysprep
    3. createa new VMfor the sysprep
    4. start VM and wait for it to shutdown
    5. delete sysprep VM
  5. Create an WIM from VHDX
  6. If template
    1. create VHDX from WIM
  7. delete VM
  8. copy VHDX and for source the WIM to the OutFolder
  9. Create VM using VHDX in OutFolder
  10. Create a scheduled task to run every Wednesday to boot the VM’s and rerun steps 4-9 exporting the Template VHDX and Source.WIM to second output folder

The process takes a few hours based on the speed of your processor and hard drive.


There are two functions in this one.

Convert-WindowsImage is a wrapper around the ps1 file so I can use it multiple times.

Start-ImageBuild is an ungodly long function I created just so I can have parameters.

At the end it’ calls Start-ImageBuild with the values that match my test environment

now Start-ImageBuild can be provided a -WIMOnly parameter if I only want Source.WIM


This is a simple Unattend.xml that:

  • Sets the Language to US English
  • Accepts the License
  • Sets the the Administrator Password to P@ssword
  • Sets 1 autologon
  • runs the FirstRun.ps1 script on logon once.


This will be copied into the image as FirstRun.ps1

  • Add and Windows Feature listed as ‘Removed’ using the attached ISO as source
  • Adds any Feature from Feature.txt
  • Adds any Feature with sub-feature from FeaturesIncludingSub.txt
  • Create AtStartup Task to run AtStartup.ps1
  • Reboot


Same as Source-FirstRun.ps1, without adding any ‘Removed’ Features

Note: I don’t actually add any Features to Template VHDX in my example but the code is there in case it’s needed. You just have to add a Template-Features.txt and/or Template-FeaturesIncludingSub.txt


Features to add to Sorce.WIM


Features including Sub-Features to add to Source.WIM


Copied into both Template.VHDX and Source.VHDX as AtStarup.ps1. This scrip is a modification of Add-WindowsUpdate James O’Neil’s Blog with some additional parameters

  • -ForceRestart  to reboot after each patch run if it needs it or not
  • -ShutdownOnNoUpdate  to shutdown once there are no additional patches.


Copied into Templat_Sysprep.VHDX as AtStartup.ps1

  • Unregistered the AtStartup Task
  • Deletes c:\Unattent.xml
  • Deletes all other files in c:\pstemp but itself.
  • Removes all ‘Available’ Windows Features
  • Use Dism to remove any overridden patches.
  • Defrag and consolidate free space (still don’t think this is necessary, but it’s not going to hurt)
  • Sysprep
    • Silent
    • OOBE
    • leave Hyper-V drivers active (this speeds up first boot so long as the VHDX is ran on the same version of Hyper-V as the machine your building on.)
    • Reboot


Script scheduled to run every Wednesday to update the Template and Source VHDX and WIM. This is a lot like Start-ImageBuild.ps1. you will have to edit the bottom of the script to match your environment

  • Has a wrapper for Convert-WindowsImage
  • Starts the Existing VM left in place by Start-ImageBuild.ps1
  • waits for VM to shutdown
  • gets the VHDX path from the VM configuration
  • for Template
    • Copies VHDX
    • Create’s new VM
    • copies in Sysprep.ps1
    • Starts VM
    • waits for it to stop
    • Delets VM
  • creates WIM form VHDX
  • for Template
    • Delets SysPrep VHDX
    • Converts WIM to VHDX
  • copies Templast_Production.VHDX and Source.WIM to OutPath

Now the Convert-WindowsImage i’m useing has been modified as noted in Part 3 of this Series

I have packaged all the files together, including the modified Convert-WindowsImage.ps1 in a single Download (This is a temporary location until I find a better place to store files.)