- Join Windows 11 to an Active Directory domain - Thu, Jun 1 2023
- Change Windows network profiles between public and private - Wed, May 24 2023
- How to map a network drive with PowerShell - Wed, May 17 2023
Microsoft offers several ways to create a customized installation image for Windows 10. If you just want to add features and drivers or remove apps, you can do this offline. DISM or a GUI tool like WIM-Witch can be used for this purpose.
For example, if you want to integrate common applications into the image, you need to install the OS. You then change this Windows instance online as desired, generalize the image, and then save it again as a WIM.
Today, hardly any admin would carry out this operation on physical PCs; instead, he would do it on virtual machines. In this post, I am using Hyper-V because it is already included in Windows 10, but VMware Workstation or VirtualBox would be equally suitable.
Installation of the guest OS using a script
Installing the operating system interactively in a VM requires many user interactions. You can speed up this step with a PowerShell script that writes Windows 10 from install.wim directly into a VHDX. Its name is Convert-WIM2VHD, and it is part of the WindowsImageTools module. You can install it by using the command:
Install-Module -Name WindowsImageTools
Afterward, you import its functions with:
Get-Command -Module WindowsImageTools
shows three functions contained in the module. Of interest to us is Convert-Wim2VHD. But before you start it, you have to make a few preparations.
Preparations for VHDX installation
The preparations for VHDX installation include providing the install.wim file from the installation ISO. However, it is not necessary to extract the WIM from it. Rather, it is enough to mount the ISO.
The next step is to find out the index of the edition you want to use. You can get the whole list using the following:
dism /Get-WimInfo /wimFile:D:\sources\install.wim
In the above example, the ISO was mounted to the drive labelled d:.
Finally, you should plan the size of the VHDX, and consider whether to use a generation 1 or 2 VM. Depending on your choice, you have to then decide between the disk layout for BIOS or UEFI. With a 64-bit version of Windows 10, you will usually prefer UEFI, and thus, a generation 2 VM.
Starting the installation
Now you can run Convert-WIM2VHD, specifying the location and the name of the virtual drive:
Convert-WIM2VHD -Path f:\images\win10-1909.vhdx -SourcePath d:\Sources\install.wim ` -index 3 -Size 40GB -DiskLayout UEFI -Dynamic
This example also uses the Dynamic switch to create a dynamic VHDX.
The function supports other parameters, such as skipping the creation of the WinRE partition (RecoveryTools and RecoveryImage), to integrate a response file (Unattend), or to add features (feature). Some of these tasks can also be done interactively after installation.
Mounting VHDX in a new VM
After the successful completion of the VHDX, which only takes a few minutes, create a new virtual machine, and attach the VHDX you just built as a virtual hard disk. When the new virtual machine is switched on, it will boot into the OOBE phase, in which you have to configure a number of settings.
For the planned customization of the image, you need to switch Windows 10 into audit mode. The easiest way to do this is to press CTRL + Shift + F3 on the first OOBE screen (select the region).
Customizing Windows 10 in audit mode
The virtual machine now restarts and automatically logs on to the built-in administrator account. It is a good idea now to install all pending updates and then restart the virtual machine. You can do this easily using PowerShell:
$u = Start-WUScan Install-WUUpdates -Updates $u
After the restart, you install the software that should be included in the image, remove features and apps, or adjust the installation according to other requirements.
If you want to continue using this reference installation to generate customized images, you should create a snapshot at this point, to which you can return after generalizing Windows 10.
Generalizing installation with Sysprep
Finally, switch to sysprep, which starts automatically in audit mode (otherwise, you can find it under %SYSTEMROOT%\system32\sysprep). If you start it without parameters, you will get a GUI where you can select the option Out-of-Box-Experience (OOBE) under System Cleanup Action, and then select the Generalize checkbox. In the shutdown options, choose Shutdown, and click OK.
Starting VM from Windows PE
After the VM is turned off, you connect your virtual DVD drive to the Windows PE ISO. This mini-OS can be downloaded from Microsoft's website (see my instructions for creating an USB stick or ISO with WinPE).
Then start the VM from the virtual DVD drive. In WinPE, call DISM at the command prompt to capture the image as follows:
Dism /Capture-Image /ImageFile:"D:\MyInstall.wim" /CaptureDir:C:\ /Name:MyInstall
In this example, DISM writes the contents of drive c: (CaptureDir) to d:\MyInstall.wim (ImageFile). If you are not sure under which letter you should access the source image, you can find out with diskpart.exe, using the following command sequence:
Subscribe to 4sysops newsletter!
list disk select disk <number> list vol
Since you are using a virtual machine, you can easily provide an additional VHDX as a storage location for the WIM. You can mount it on the host OS after the VM has been shut down again and extract the WIM image from the VHDX.
Join the 4sysops PowerShell group!
Your question was not answered? Ask in the PowerShell forum!
Hey Wolfgang, great post there! I was used to use WDS services to capture my template into a WIM, however I think this process is more universal and I will switch to this definitely!
As you recommend, a checkpoint should be always created before sysprep attempt, as you can make a small mistake and start again all over. It is also quite common to manage the template over time and for that checkpoint is a must.
Hi Leos, great to hear that you like my approach for creating a Windows 10 custom image!
The issue with my approach was, that when I did the image via WDS capture, I was only able to deploy it via WDS. When I tried to export the WIM and place it on an USB stick, once it booted, the setup showed me "no images available". Even tried to export boot.wim from WDS but that did not help.
I was checking few posts on the web but none of them helped and I did not want to spend too much time on it.
Thank you for the post, as always it's very informative.
However I do recommend you guys to take a look at the 'OSDBuilder' PowerShell module, it does the whole process you described for you without needing a VM.
Im afraid that with the module shared, you are unable to install custom software and do other configuration stuff like desired for your organization.
This is the main goal to create a custom template, at least for me. 🙂
To use VirtualBox, what are the right params to use the Convert-WIM2VHD command? Since VirtualBox doesn't support VHDX (I was able to boot a VM into WinPE on VirtualBox).
You can use the parameter "-VhdFormat VHD" to create a .vhd which then can be used by VirtualBox.
But in that case, I can't use it to prepare UEFI images then?
Yes, you can. Only Hyper-V Manager won't allow you to use a VHD for a Gen2 VM.
Thanks a lot!
Loved the article.
FYI, on my Windows 10 20H2 ISO that I created using the media creation tool, the file “install.wim” is actually called “install.esd” but it otherwise works.
When i try to personalize things, it is asking for product key.
Awesome, thank you!
The only issues I had were I created the VM first and tried to apply the wim, I see from the instructions to create the vhdx FIRST and then create the VM to attach the drive.
Also, the commands didnt seem to like when I used quotes and having spaces in -path or -source path, once the spaces were removed and the quotes everything worked!
Convert-WIM2VHD -Path C:\VirtualMachines\New.vhdx -SourcePath C:\SHB\Captures\Automated\SHB_REF_2022-2-16_0918.wim -index 1 -Size 64GB -DiskLayout UEFI -Dynamic
Successfully applied a large Windows 11 wim image with Office installed for testing that I had previously built within SCCM / OSD on another network (so PXE booting wasn’t an option on this enclave).