Create a bootable Windows 10 Autopilot device with PowerShell!

The most common complaint that I’ve received from people over the last few years around Intune / Autopilot / Modern Management is that people find it frustrating how much effort is involved in getting a device prepared to handover to a client for Autopilot enrollment.

I totally agree – the sales pitch we are all given is that your staff can go out to a big-box store, buy a laptop and in minutes be greeted with a “welcome to mega-corp” login screen.

What is never told to us is that before we do any of this, we need to:

  • make sure a CLEAN copy of windows 10 is installed on the device – which it never is.
  • Capture the hardware hash of the device and upload it to Intune.
  • Finally, if the device is already past the OOBE, re-image the device and hand it over to the staff member..

Hardly the autonomous, streamlined sales pitch we’ve been sold – is it?

Well, I’m here to say I want to make it a little less painful with my first published PowerShell module – Intune.USB.Creator!

This is a solution developed over the last few years and road-tested with multiple clients and environments – something that is reliable enough that I’m happy enough to share it as a complete solution – something I rarely do due to being an obsessive perfectionist…

Let’s get into how we use it!


First things first, we need to make sure the device you are going to use to build the Autopilot device has a few pre-requisites:

The module was written primarily for PowerShell 7 – if you don’t have it yet, there’s a bunch of ways to get it on your machine. Below is probably the easiest of the lot..

Some of the helper functions rely on other modules – so let’s install those (using PowerShell 7 of course..)

The module uses Windows 10 installation media to create the bootable media. This can be procured from many locations – if you do not have access to this, someone you work with will – just make sure you have a copy of the latest *.iso on your device.

Finally, let’s install the Intune.USB.Creator module..

How to use

Once all the pre-requirements are installed, plug a USB into our device and let’s create an Autopilot provisioning device.

Open up PowerShell 7 as an administrator and we will type in the following command:

Hitting enter will kick off the device provisioning code..

A few things to note on each parameter:

  • WinPEPath (Required) – I’ve put a copy of WinPE up on my own storage account – feel free to use it, but if the cost of storage ends up too much, I will take this down. So grab a copy now and store it locally. Consider this fair warning.
  • WindowsIsoPath (Not required) – as mentioned in the pre-requirements section, you need to source your own copy of Windows 10. This shouldn’t be difficult. Try and get a copy of the “multi-edition” so you can build different variants if required. If you don’t provide a path to a copy of Windows 10, the device will still be provisioned, but there will be nothing added to the solution except for WinPE.
  • GetAutopilotCfg (Not required) – this is a simple switch to allow you to log in to an Azure tenant and capture the Autopilot configuration files. If you omit this, you will end up with a provisioning device that installs windows 10 and does nothing else.

Once our USB has been created, all that is required to do is plug it into our target device and boot from it.

WinPE will load and trigger the built in provisioning script which will load the operating system onto the device and inject the Autopilot configuration file.

Once the device has been provisioned – remove the USB and reboot. We should now be greeted with the standard Out of Box Experience, ending with the ability to log in to the tenant we captured the Autopilot configuration from!

Pretty cool, if I do say so myself.

Using this solution should provide you with a bootable USB that will get you from “out of box” to “ready to enrol” in less than 5 minutes.

As usual, source code for everything demonstrated here is available on GitHub, the module itself is available on the PowerShell Gallery and I am always up for a chat on Twitter.

— Ben


  1. Jamie Knowles Reply
    May 5, 2020 at 9:16 am

    Thanks for sharing this, it’s excellent! I’ve got 2 autopilot profiles in my tenant but I didn’t get the choice. The warning I got onscreen during the script, ‘Grabbing Autopilot config file from Azure..’ -> ‘Multiple Autopilot policies found – select the correct one..’ -> ‘WARNING: The term ‘Out-ConsoleGridView’ is not recognised as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if path was included, verify the path is correct and try again.’ I installed all the modules you listing so I guess i’m missing one, could you let me know which?

    • Jamie Knowles Reply
      May 5, 2020 at 1:38 pm

      Just to confirm I had to run -> ‘Install-Module Microsoft.PowerShell.ConsoleGuiTools’ to install the missing module and then all worked šŸ™‚

      • Ben Reply
        May 6, 2020 at 12:04 am

        Yep – totally forgot to add that in the pre-reqs – I’ve now included it!

        • PieKie Black Reply
          May 6, 2020 at 2:58 pm

          Grabbing Autopilot config file from Azure.. WARNING: Could not load file or assembly ‘Microsoft.IdentityModel.Clients.ActiveDirectory, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35’. Could not find or load a specific file. (0x80131621).
          I get this error when trying to create the media. The process does complete but I never get the prompt to enter Azure credentials to grab the autopilot profile file. Installed all required modules as per article. Anything that I might be missing.

          • PieKie Black
            May 6, 2020 at 5:52 pm

            I found the issue. It was related to the Scope of ExecutionPolicy.
            Get-ExecutionPolicy -list
            Scope ExecutionPolicy
            —– —————
            MachinePolicy Undefined
            UserPolicy Undefined
            Process Undefined
            CurrentUser Bypass (this was set to Restricted for some weird reason)
            LocalMachine Bypass

          • Nick
            May 21, 2020 at 9:31 am

            I am still getting the same error as you on a brand new built laptop so feel like I am still missing a dependency.

  2. Philippe Reply
    May 22, 2020 at 9:26 am

    Hi Ben,
    I’ve installed the Poweshell7 and all the modules.
    I have the and W10 iso in a local folder (the path are OK)
    But when I try to Publish-ImageToUSB … the script start 2 seconds (I can see the beginning off the script) and the powershell console is switch off. I don’t have time to see where it stop :/
    I don’t have any idea where to looking for now to solve this problem, do you have any idea ?

    • Philippe Reply
      May 26, 2020 at 11:10 am

      I found the problem, not enough space left in my hard drive, the script close at “Get-RemoteFile -fileUri $winPEPath -destination $usb.downloadPath -expand” :c/
      It’s ok now :c)
      After, I’ve got a problem with the .iso : no .wim file, so I’ve created one with dcim (Windows Education (4)) and replace Region get wim from ISO by “Get-RemoteFile -fileUri “D:\W10_autopilot_install\install.wim” -destination $usb.WIMPath” to test.
      Everything looks fine now :c)
      Thanks a lot for your work !

  3. Oskar Reply
    May 28, 2020 at 10:58 am

    I’ve not looked at the code, but I can’t see in the blog post how the issue with capturing and uploading the HW hash is adressed. Is this still a pre-req or something that is done at the same time as getting the AP config?

    • Ben Reply
      June 2, 2020 at 5:35 am

      By utilizing “offline autopilot enrollment” we bypass the need to pre-load the hardware hash into the environment. If your autopilot policy is configured for it you can set it to throw the device hw hash into your environment so that it will always be a member of your tenant on consecutive resets / reimages.

  4. Per Salmi Reply
    May 28, 2020 at 2:33 pm

    Hi! While testing the module I find that the tenant must allow personally owned devices in the device enrollment restrictions to let the end user enroll the device. Is there a way to use it even if personally owned devices are blocked? You get a 80180014 error after the account login stage when personally owned devices are blocked.

  5. Mike Reply
    June 23, 2020 at 7:56 pm

    Does this USB Creator also support legacy booting from floppy on older devices(mbr vs gpt)? It works great on newer uefi bios systems but I run into issues with older Dell Optiplex systems from 10 years ago that do not support uefi. Will have to test more.

    • Mike Reply
      June 23, 2020 at 8:02 pm

      correction: booting from USB on older devices…

  6. Esko K Reply
    June 25, 2020 at 11:52 am

    Clearing Disk: 1 Creating New Partions New-Partition: C:\Users\xxxxxxxxxx\Documents\PowerShell\Modules\Intune.USB.Creator\\Private\Set-USBPartiton.ps1:22 Line | 22 | ā€¦ = (New-Partition -DiskNumber $diskNum -Size 2GB -AssignDrive ā€¦ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Not enough available capacity Activity ID: {5db62cc6-a32a-4ff4-a6ce-0e4709f7c701} New-Partition: C:\Users\xxxxxxxxx\Documents\PowerShell\Modules\Intune.USB.Creator\\Private\Set-USBPartiton.ps1:23 Line | 23 | ā€¦ s.drive2 = (New-Partition -DiskNumber $diskNum -UseMaximumSize -Assig ā€¦ | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Not enough available capacity Activity ID: {f206cbdf-bc13-4d13-a6b1-9547397bdddd} Writing WinPE to USB.. WARNING: You cannot call a method on a null-valued expression. Writing Install.wim to USB.. WARNING: You cannot call a method on a null-valued expression. Writing Autopilot to USB.. WARNING: You cannot call a method on a null-valued expression. Grabbing provision script from GitHub.. WARNING: The filename, directory name, or volume label syntax is incorrect. : ‘C:\Windows\System32\:\scripts\Invoke-Provision.ps1’

  7. Logan Case Reply
    June 25, 2020 at 3:01 pm

    How can we access your WinPE files to download them? I looked for a link but couldn’t find anything.

    • Ben Reply
      June 28, 2020 at 5:39 am

      Look closer. “”

  8. Esko K Reply
    June 29, 2020 at 4:42 am

    I had to remove all partitions from usb memory before I could finish creating the bootable device.

  9. Mats Markussen Reply
    June 30, 2020 at 1:49 pm

    Receive an error when trying to create the usb

    Writing WinPE to USB..āˆš

    Writing Install.wim to USB..āˆš

    Writing Autopilot to USB..

    WARNING: You cannot call a method on a null-valued expression.

    Grabbing provision script from GitHub..
    WARNING: Could not find a part of the path ‘D:\scripts\Invoke-Provision.ps1’.

    Seems like it fails to copy the contents of the WinPE folder to the newly created partition.
    Downloaded and use a local version of WinPE

    • Mats M Reply
      July 1, 2020 at 1:57 pm

      never mind me, didn’t notice powershell 5 launched even though 7 was installed

Leave A Comment

Please be polite. We appreciate that. Your email address will not be published and required fields are marked