I just read a quick debate on Twitter between Johan Arwidmark and Mike Terrill on the topic of which path makes for smaller Windows Images when you are doing the quick monthly incremental updates. You know them as Microsoft “Patch Tuesdays”. So just yesterday (Aug. 8, 2017) the most recent cumulative update came out. And I downloaded it with every intention of firing up Hyper-V, connecting to my Win10-Build VM and proceeding as normal. I don’t do reference images as such, nor do I use MDT. I literally run Windows Update interactively while logged in as local admin on my VM. I reboot the VM, login again, try WU again, make sure everything has been applied. Then I pull out my little sysprep cheat sheet and do a sysprep with unattend.xml (for my customization) and OOBE and shutdown.
I then mount the Virtual Hard drive (.vhd) for that VM within my host OS. I run DISM command to capture/compress as much as possible to get the image size down. With Win10+Office2016 I hover around the 6.75GB to 7.5GB range in terms of the .wim file, using this process. But I was curious to look at how easy, or difficult it was to simply mount the .wim file and insert/import the Cumulative Update packaged as a .msu file from the MS website directly. I have known for a while this command line flag existed but never tried it out until I read the debate between Johan and Michael.
Full credit goes to Matt Shadbolt (MSFT) for this Technet article where I found a Powershell script to run all the DISM commands needed to update a .wim file:
Applying Windows Updates to a base WIM using DISM and Powershell
So I ran a second round of update just for comparison sake on an unaltered, un-updated .wim file using the DISM. I found a Powershell script that help speed this up a bit, and required less typing and pasting of commands to do all the steps. I first downloaded the Cumulative Update from the Microsoft Update Catalog and put into my F:\drive in a folder called “Updates”.
I took Matt Shadbolt’s PS script and modified it slightly. I added the /Cleanup-Image step and also the /Export-Image at the tail end of the script here:
$UpdatesPath = "F:\Updates\*"
$MountPath = “C:\test\offline”
$WimFile = “E:\shared\WIMs\images\2.wim”
DISM /Mount-Wim /WimFile:$WimFile /index:1 /Mountdir:$MountPath
$UpdateArray = Get-Item $UpdatesPath
ForEach ($Updates in $UpdateArray)
DISM /image:$MountPath /Add-Package /Packagepath:$Updates
Start-Sleep –s 10
Write-Host "Updates Applied to WIM"
DISM /Image:$MountPath /Cleanup-Image /StartComponentCleanup /ResetBase
DISM /Unmount-Wim /Mountdir:$MountPath /commit
DISM /Export-Image /SourceImageFile:$WimFile /SourceIndex:1 /DestinationImageFile:"F:\2.wim"
Now, let’s go back to Johan’s original tweet:
In my test I did the first run with my Hyper-V Build VM
- Run Windows Update
- Run Windows Update one more time
- In Host OS mounted VHD, captured using DISM cmdline
- File size for 1.wim = 7,141,081,712Bytes (or 7.141GB)
Second run on an original .wim file captured previously from that same Hyper-V .vhd using Matt Shadbolt’s slighlty modified Powershell script (DISM with /Add-Package with some cleanup steps).
- Mount .wim
- File size for 2.wim = 7,144,702,046Bytes (or 7.144GB)
So caveats here are this was one run with the August Cumulative Update for Win10-1703+Office2016. Your mileage may vary on successive runs. But as near as I can tell using DISM /Add-package works just as well as doing a “Build+Capture” in your MDT Build Lab and Hyper-V environment as near as I can tell. The differences I am seeing are not 1GB but closer to ~3MB total difference between the two paths.