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!
Pre-Requirements
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..
![](https://i1.wp.com/i.imgur.com/u4HOn0y.gif?w=1170&ssl=1)
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.
![](https://i2.wp.com/i.imgur.com/v9Ls50M.gif?w=1170&ssl=1)
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!
![](https://i0.wp.com/i.imgur.com/KcMT5OP.gif?w=1170&ssl=1)
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
42 comments
Jamie Knowles
May 5, 2020 at 9:16 amThanks 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
May 5, 2020 at 1:38 pmJust to confirm I had to run -> ‘Install-Module Microsoft.PowerShell.ConsoleGuiTools’ to install the missing module and then all worked 🙂
Ben
May 6, 2020 at 12:04 amYep – totally forgot to add that in the pre-reqs – I’ve now included it!
PieKie Black
May 6, 2020 at 2:58 pmGrabbing Autopilot config file from Azure.. WARNING: Could not load file or assembly ‘Microsoft.IdentityModel.Clients.ActiveDirectory, Version=5.0.5.0, 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 pmI 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 amI am still getting the same error as you on a brand new built laptop so feel like I am still missing a dependency.
Philippe
May 22, 2020 at 9:26 amHi Ben,
I’ve installed the Poweshell7 and all the modules.
I have the WinPE.zip 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
May 26, 2020 at 11:10 amHi,
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 !
Oskar
May 28, 2020 at 10:58 amI’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
June 2, 2020 at 5:35 amBy 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.
Per Salmi
May 28, 2020 at 2:33 pmHi! 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.
Mike
June 23, 2020 at 7:56 pmDoes 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
June 23, 2020 at 8:02 pmcorrection: booting from USB on older devices…
Trace
October 12, 2020 at 6:06 am@Mike what error do you get on older devices? Is it invalid partition table? If so I’m getting the same issue. is there a work around?
Esko K
June 25, 2020 at 11:52 amClearing Disk: 1 Creating New Partions New-Partition: C:\Users\xxxxxxxxxx\Documents\PowerShell\Modules\Intune.USB.Creator\1.0.1.285\Private\Set-USBPartiton.ps1:22 Line | 22 | … ss.drive = (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\1.0.1.285\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’
Logan Case
June 25, 2020 at 3:01 pmHow can we access your WinPE files to download them? I looked for a link but couldn’t find anything.
Ben
June 28, 2020 at 5:39 amLook closer. “https://githublfs.blob.core.windows.net/storage/WinPE.zip”
Esko K
June 29, 2020 at 4:42 amI had to remove all partitions from usb memory before I could finish creating the bootable device.
Mats Markussen
June 30, 2020 at 1:49 pmReceive 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
July 1, 2020 at 1:57 pmnever mind me, didn’t notice powershell 5 launched even though 7 was installed
Kris
July 12, 2020 at 12:48 amGrabbing provision script from GitHub..
Grabbing PWSH 7..
VERBOSE: Destination: D:\scripts\pwsh
VERBOSE: About to download package from ‘https://pscoretestdata.blob.core.windows.net/v7-1-0-daily-20200709/PowerShell-7.1.0-daily.20200709-win-x64.zip’
WARNING: Response status code does not indicate success: 404 (The specified resource does not exist.).
how can i workaround this
Thanks,
Kris
Kris
July 12, 2020 at 9:59 pmhi Ben
getting below error any idea why
Number TotalSize(GB) Name
—— ————- —-
0 238.47 SAMSUNG SSD CM871a M.2 2280 256GB
1 7.21 Verbatim STORE N GO
Please select Desired disk number for USB creation: 1
Clearing Disk: 1
Creating New Partions
Writing WinPE to USB..√
Writing Install.wim to USB..√
Writing Autopilot to USB..√
Grabbing provision script from GitHub..
Grabbing PWSH 7..
VERBOSE: Destination: D:\scripts\pwsh
VERBOSE: About to download package from ‘https://pscoretestdata.blob.core.windows.net/v7-1-0-daily-20200709/PowerShell-7.1.0-daily.20200709-win-x64.zip’
WARNING: Response status code does not indicate success: 404 (The specified resource does not exist.).
Ben
August 18, 2020 at 1:38 amThere was an issue with the current build of the PowerShell 7 installation media. This has been fixed up and a fix applied to a new build of the module. Please update locally.
marcellos
July 14, 2020 at 5:20 pmThis is amazing work! I am using this all over the place now. Can you explain how you made the custom WinPe that behaves that way, and why your bootable USB works with Secure Boot enabled, but none of the ones i create work? Would it be possible to automate the exit as well so that it is completely unattended like the classic installers we create today with AutoUnattend.xml on the root?
Ben
August 18, 2020 at 1:32 amThe WinPE media was captured from a rough demo of the same concept that someone else was trying to build but wasn’t working very well. Unattend.xml files can be used with this solution as well – they need to be placed in a specific location within the usb partitions – the provisioning script does look for them.
Santeri
July 29, 2020 at 8:41 amHi! Thanks for sharing this excellent way of creating USB installers with Autopilot. I still have one big problem with this. No matter what I try to do, it will never prompt me to enter Azure credentials for obtaining the autopilot configuration. I have tried with multiple computers etc, but the problem still persists. Another strange thing is that it won’t let me choose the destination disk, it just uses my computer’s internal SSD by default. If I enter the parameter “-DiskNumber” I can get it to choose the right disk. Despite, it still wont get the Autopilot configuration from Azure. What could cause this? I have installed all prerequisites listed and I am using Powershell 7.
Ben
August 18, 2020 at 1:29 amMake sure you are using the latest version of the module – there’s been a lot of bug fixes added recently that should fix the problems you are having.
MK
August 6, 2020 at 12:42 pmHaving the same issue Grabbing Autopilot config file from Azure.. WARNING: Could not load file or assembly ‘Microsoft.IdentityModel.Clients.ActiveDirectory, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’. Could not find or load a specific file. (0x80131621). Execution policy is set to unresticted. Any idea what is missing?
Ben
August 18, 2020 at 1:26 amAs mentioned previously, this is an issue with not having the auth libraries accessible in PowerShell 7. Please install the module in PowerShell 5.1 first and try again.
MK
August 19, 2020 at 9:30 pmAwesome! Thanks! That worked!
Corey
August 7, 2020 at 5:37 amI’m having an issue and perhaps it’s my lack of understanding of how this is supposed to work. During the creation of the USB drive it gets partitioned at 2GB which seems correct based on the Set-USBPartition command, however it looks like I need a larger partition. I get a message saying:
Disk number selected.
Clearing Disk: 1
Creating New Partions New-Partition:
Not enough available capacity
I’ve got heaps of space, they’re 32GB USB drives, but the preceding steps are formatting it to 2GB, it carries on and eventually says it’s done. However if I try to use that USB I get the error that “Install.wim” isn’t found, I guess that’s because it couldn’t fit on the 2GB partition. I copied the USB onto another one and extracted the install.wim file and manually copied it into the images folder and gave that a go, it got further however I’m missing the “imageIndex.json” file which I guess hasn’t been created as part of the failed install.wim copying, what am I doing wrong?
Ben
August 18, 2020 at 1:25 amNot sure. I’ve recently updated the module to fix a few usability bugs – perhaps update and try again.
If you continue to have issues, please raise an issue ticket on the project page – https://github.com/tabs-not-spaces/Intune.usb.creator
Marcus Horne
August 14, 2020 at 7:19 amGetting this error when trying to downlad the Autopilot config?!
Grabbing Autopilot config file from Azure..
WARNING: Could not load file or assembly ‘Microsoft.IdentityModel.Clients.ActiveDirectory, Version=5.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35’. Could not find or load a specific file. (0x80131621)
Ben
August 18, 2020 at 1:22 amThat error is related to trying to use the ADAL auth libraries in PowerShell 7 but not having them accessible in PowerShell 5.1. Try installing the module in 5.1 first and it should resolve the problem.
Aaron
August 14, 2020 at 11:57 amThis works great apart from it defaults the keyboard to US English. In my policy it is set to UK English, and once it has gone through OOBE language settings show that it is applied except fro Keyboard which is system default. Any ideas what is causing this?
Ben
August 18, 2020 at 1:20 amUsing the wrong installation media for your region i’m guessing..
Mark Lajer
October 22, 2020 at 9:04 pmWe see the same thing. We set Keyboard to Danish but installing English iso. Even if we select Danish in the installation process the keyboard is US English.
Gringo
October 8, 2020 at 5:30 pmerror:
Creating New Partions
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’.
Drive D: becomes no content or data inside.
Brian H
November 1, 2020 at 11:19 pmGreat work – thank you for sharing. Is it possible to create an .iso output file instead of the USB Bootable ? (One could always us Rufus or other to convert from ISO to USB)
bruno
November 23, 2020 at 5:02 pmI noticed that when I run this on a laptop, I get “the request is not supported” almost immediately after the “Setting power policy to ‘High Performance’ .. ” message comes up. Looking at the script, I also see the next step is a Welcome Screen display.
Is there something special I should do for Laptops or something different? I have tried on 20H4, 2004, 1909, and 1903 versions of Windows and still cannot get this to run on Laptops. Love to hear any thoughts on the matter.
Trace
November 28, 2020 at 4:50 amI’m trying to run this with what is now PowerShell 7.1.0 and am getting errors that did not exist previously. Is there a way to force it to use the older version of PS 7? I have tried copying the \Scripts\pwsh\ from an older thumb drive, but that somehow has environmental variables to a different tenant. Any help would be appreciated!
Trace
November 29, 2020 at 5:29 amSo the script PublishImagetoUSB.ps1 is calling a command to automatically download the latest version of PS7, which is now PS7.1 downloading a ZIP version and saving it to the scripts folder of the USB drive as \scripts\pwsh. When using 7.1 it was throwing an error about Power settings and performance in the WINPE environment. I finally got this to work by downloading 7.0.3 from https://github.com/PowerShell/PowerShell/releases/download/v7.0.3/PowerShell-7.0.3-win-x64.zip deleting the contents of the pwsh folder, and putting this version in there. (I was having a separate issue, and I assumed they were related — they were not!) Hope this helps others.
Comments are closed.