Building ISO Files with PowerShell 7

A function that’s been part of my toolkit for a long time is New-ISOFile by Chris Wu. This excellent little function allowed you to build an ISO file directly from PowerShell, even a bootable one.

I came to use it recently on an automation project with PowerShell 7 and discovered there was some compatibility issue that prevented it from working. I noticed that the original Technet site that the function came from originally is now gone, so I considered this an opportunity for some code review and hopefully produce a revised function that works with PowerShell 7.

The Issue

The actual issue was fairly straight forward, Microsoft have changed the functionality of the Add-Type CMDlet, something New-ISOFile depends upon. The difference between 5.1 and 7 is here:

In 7……

In 5.1…..

Notice that -CompilerParameters has become -CompilerOptions, the latter now being a simple string input rather than an object.

Other Changes

The first change to New-ISOFile was to add a switch block to detect the PowerShell version, and call the CMDlet appropriately.

A few other things I’ve done are mostly to streamline the code for my purposes in an automation workflow, as opposed to running it interactively at the PowerShell prompt.

To start, I’ve removed clipboard and pipeline support, neither of which I needed. Then I’ve restructured the code to satisfy my OCD and to make it more readable (to me at least).

There is a lot more error handling (if something is running in the middle of a long automation process, I want to know if it breaks). Lastly, I’ve added a lot more verbose output and comments so hopefully it’s easier to follow, and to remind future me how it works.

An Example: Build a Custom Bootable Windows ISO with PowerShell

Something I’ll be using this during an automation workflow to build a custom bootable ISO for Windows. This involves taking a piece of stock Microsoft media and building a custom ISO with the following changes:

  • Remove the “Press any key to boot from CD or DVD” and boot immediately with no interaction.
  • Inject an autoUnattend.xml to perform an unattended Windows installation.

Step 1: Mount the Stock ISO

The first step is to mount the ISO and copy all of the files to a temporary location. This can easily be achieved with PowerShell’s Mount-Image and Copy-Item CMDlets, but for demonstration purposes this has been hand cranked:

Step 2: Copy in an autoUnattend.xml

There are various locations that the installer will look to to pick up an autoUnattend file, have a look here for the search order. In this case, it will be added to the root of the media. I won’t go into details on how to prepare this file, but suffice to say many blogs have covered this in great detail already. The end result should look like this:

Step 3: Some Code, Finally

Ok, so enough clicking on things like a chump, let’s open PowerShell and get this show on the road:

The source and destination are fairly self explanatory. The boot file specified is efisys_noprompt.bin, this is a boot file that Microsoft provide direct on the media for exactly this scenario, neat.

The function kicks back the file object in case you need to grab this as an input in a later calling function.

Step 4: Profit

The resulting ISO will automatically boot and install Windows with the options specified in the autoUnttend, sweet.

Conclusion

Ok, so this might have been more about creating a custom Windows ISO, but hopefully the revised function will be useful to PowerShell 7 users (which is hopefully most by now, if not, why not? 🙂 )

Thanks again to Chris Wu for his original efforts.

The new function is available from The Dot Source Github.

Leave a comment