Digging up the past: converting Windows ISOs to bootable VHDX-files

In this post I will show you how to convert (publicly available) Windows ISO files to bootable VHDX-files you can use over and over again in your lab environment.

This all started while doing research for a sequel to “Your own Microsoft 365 lab” which, as you can guess, is about setting up VMs for testing in your lab. I ran into something a some of you probably remember, from waaaay back in 2020, and I have the uncontrollable urge to revisit it 😊.

No worries, part 2 is still being published, probably somewhere next week. I just had to get this one out of my system first.

One script to rule them all

Now, this all comes down to one script. One. Single. Script. It’s called “Convert-WindowsImage”, and it has a long and tumultuous past. It allows you to create pre-cooked VHDX-files from Windows & Windows Server ISOs, which you can then use again and again when building lab VMs.

And if you’re a bit lazy, like me, you’ll like that it saves you the time of clicking through the start of the setup-process.

History repeating itself

But what about the eagles?

Starting out as a script in the PowerShell Gallery, ‘maintained’ by Microsoft, which hasn’t seen an update since 2016. The project site on GitHub is hidden somewhere in the MicrosoftDocs repository.

Along came Mr. Powers-Hell and friends, who made a pretty damn cool PowerShell module called Intune.HV.Tools, and they really, really needed to use this script in it. They tried to contribute to the original project but their pull requests weren’t answered. And so, they created their own version, calling it “Hyper-ConvertImage” (PowerShell Gallery, GitHub).

Unfortunately, both the Hyper-ConvertImage and Intune.HV.Tools projects have not seen any commits in the last two years. Back then, it was new and shiny, but I guess the buzz around it has kind of died down. I thought the idea was great, so I dug a little further.

Turns out someone‘s been working on the same thing in the shadows. Since 2019, using the same original script by Microsoft, even using the same name as the original: Convert-WindowsImage. But, and this is an important but: this one is still receiving updates.  

Well, the last one was on October 30th of last year (2021), but I don’t expect this script needs to be changed every week to keep it up-to-date. I’d expect there to be occasional updates for new Windows versions but that’s about it.

Let’s put it into practice

This script isn’t hard to use at all. It does have some quirks and it may not be the most user-friendly ever, but it sure does the job.

Heads up: this script does not work in PowerShell Core and requires elevation. You will need to start a ‘classic’, elevated Windows PowerShell session.

Dot Warner from Animaniacs
Hellooo nurse!

Loading it is, of course, the first step. Let’s dot-source it.

For those unfamiliar with dot sourcing: the leading dot makes sure the script is executed in the current scope. If you forget that little bugger, the script will create it’s own scope and the functions inside it will not be made available outside it. The second dot isn’t really relevant and is simply part of the scripts path.

. .\Convert-WindowsImage.ps1

There’s only one function in this script, and it’s surprisingly called Convert-WindowsImage. This function is now available as a cmdlet. Be aware that autocomplete may try to reference the script file again if you try to use it in the same directory.

So many choices

To convert an ISO to a VHDX, this script will need to know some more details. The following parameters are required:

  • SourcePath points it to the ISO file you want to use.
  • Edition selects a specific Windows edition to be used.
  • VHDFormat instructs the script to create either a VHD or VHDX file. I’m just guessing but you’re going with VHDX , amiright?😊
  • SizeBytes defines the size of the disk to create.
  • DiskLayout selects how the partitions will be set up, I suggest you use UEFI here (for generation 2 VMs).
  • VHDPath point is to where you want the virtual disk file to be placed.

The most mysterious in the list above is probably Edition. A Windows ISO usually contains more than one edition. As an example: my Windows 11 ISO (coincidentally) has 11 of them, ranging from “Windows 11 Home” to “Windows 11 Pro N for Workstations”.

If you are not sure which editions are available in your ISO, you can simply use -Edition LIST to have the script dump out all available options.

It will also throw an error but just ignore that. Also, you will still have to define other parameters like VHDFormat and DiskLayout, as they are simply required or cause problems if omitted.

Convert-WindowsImage -SourcePath ..\ISOs\Win11_English_x64_21H2_22000708.iso -VHDFormat VHDX -Edition LIST -DiskLayout UEFI;

There are many more parameters to play with, but these are the importantestest ones.

Make me a disk

The easiest way to show you how it’s done, is to provide a simple example.

Convert-WindowsImage -SourcePath ..\ISOs\Win11_English_x64_21H2_22000708.iso -VHDFormat VHDX -Edition 6 -SizeBytes 50GB -DiskLayout UEFI -VHDPath .\Win11Pro-21H2-22000708-test.vhdx;

You’ll notice I specified the Edition as a number. If you use -Edition LIST, it will also tell you which index number it is. You will need to use this if names are ambiguous as they’re, apparently, partially matched.

In a nutshell, this script mounts the ISO and newly created, and formatted partitions on the virtual disk on your device. It then uses DISM.EXE to apply the Windows image you selected, makes it bootable with BCDEDIT.EXE and (unlike most of my own scripts) cleans up the mess it made.

Fun fact: you can now mount this VHDX and manipulate it all you want. I’m still exploring what I can do with it. If I come up with anything really clever, I’ll be sure to write about it.

Nailed it!

If all went as planned, you will now find a bootable VHDX-file in your current directory. Let’s nail it to a VM.

I do suggest you make a copy of the VHDX file, and store the one you just created for later use. Seeing as that was kind of the whole idea here.

  • Create a new VM in Hyper-V Manager
  • Up until “Connect Virtual Hard Disk”, select all the things you usually select.
  • Select “Use an existing virtual hard disk” and point it to the copy of the VHDX you just made.

You did make a copy when I told you to, didn’t you?

  • Finish up and configure the stuff Hyper-V’s wizard doesn’t let you do immediately (like Secure Boot and TPM and such).

That’s it. You may now start your VM. You’ll find it doesn’t start with Windows Setup but immediately jumps to OOBE.

Rinse and repeat for additional VMs.

Let me repeat: there’s lots of ways to set up a lab environment with VMs of your choosing. This is merely one I found handy, but it doesn’t mean it’ll be the right fit for you. In the upcoming post “Your own Microsoft 365 lab – part 2”, I will show you how to do it manually.

One Comment

Let me know what you think!

This site uses Akismet to reduce spam. Learn how your comment data is processed.