When migrating to the modern Autopilot world, if you are not purchasing net-new devices, you may find yourself having to rebuild current ones.
This means getting these devices into Autopilot devices. The most popular option (and rightly so) is to use the Get-WindowsAutopilotInfo script, whether that’s the official one or the community edition
Sometimes though, you might want a more simple solution, something a bit plug-and-go. This is something I recently came across so thought why not script it!
V2.0 update – Now supports language/locale selection for ISO
You can grab the script from GitHub here
Or from PowerShell Gallery:
Install-Script -Name create-windows-iso-with-apjson
The result is a new script to create a Windows ISO, running the script will do the following:
- List your Autopilot profiles in a grid-view to select the one to use
- Prompt for a language for the ISO
- Grab the JSON for you
- Popup the OS choice, this is grabbed directly from Microsoft to list only the currently supported versions
- Create a new folder in c:\temp to work from
- Grabs the ISO URL using the excellent Fido from Pete Batard
- Downloads the ISO
- Mounts the ISO
- Grabs the Windows Professional WIM from within in
- Mounts the WIM and injects the autopilot JSON
- Converts the new WIM to an ISO (using oscdimg)
- Cleans up everything but the ISO
As with all scripts, you can supply parameters to use an Azure App Reg for the Autopilot profile part so you could run this on an automated schedule.
When using this with an Autopilot dynamic group, the rule needs to be:
(device.devicePhysicalIDs -any (_ -startsWith "[ZTDid]")) -or (device.enrollmentProfileName -eq "OfflineAutopilotprofile-PROFILEIDHERE")
Replace PROFILEIDHERE with the ID listed in the initial popup when selecting the profile to deploy (it’s also in the address bar within the Intune portal)
Hopefully you find this useful!
Trying to execute this script but i got only problems and more problems. Apparently there is some locations that are banned but if i try from Nederland or usa still the same.
Dont know what to do. Please help !
I have a big problem with this
Error: We are unable to complete your request at this time. Some users, entities and locations are banned from using this service. For this reason, leveraging anonymous or location hiding technologies when connecting to this service is not generally allowed. If you believe that you encountered this problem in error, please try again. If the problem persists you may contact Microsoft Support – Contact Us page for assistance.
Start-BitsTransfer: C:\Users\haris\Documents\PowerShell\Scripts\create-windows-iso-with-apjson.ps1:526
Line |
526 | $download = Start-BitsTransfer -Source $windowsuri -Destination $isof …
| ~~~~~~~~~~~
| Cannot validate argument on parameter ‘Source’. The argument is null or empty. Provide an argument that is not null or empty, and then try the command
| again.
RuntimeException: C:\Users\haris\Documents\PowerShell\Scripts\create-windows-iso-with-apjson.ps1:528
Line |
528 | [int] $dlProgress = ($download.BytesTransferred / $download.Bytes …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Attempted to divide by zero.
That happens sometimes, it usually fixes itself. In the meantime you can download an ISO and use the parameter to use that instead
I am a newbie Andrew. If you dont mind me asking, how to “use the parameter to use that instead”.
If you run it like this:
create-windows-iso-with-apjson.ps1 -isopath “c:\path-to-iso.iso”
Hey, I would love, if you could edit the script to ask for existing images on the harddrive instead of always downloading the newest ISO. It´s just a extra fault factor, when a download is not working, or Microsofts Servers don´t let you download..
If you use the -isopath parameter when launching it, it will use whatever iso you point it towards
Is this solution still working? i tried multiple times and everytime it is failing at the first step of the oobe for “securing device”, when i check the regedit key it says that it is failing because the device is not registered. i saw your comment that microsoft did some change and is blocking if enrollment of personal device is blocked, but i’m not blocking this parameter either.
It should work as long as personal devices are allowed
i’ve opened a case with microsoft. The solution is to be on 24H2. No longer possible from 23H2.
Hi Andrew,
Really interesting article. I got it working. I did have a weird situation though.
Namely, the weird thing is that the process never got me through the autopilot setup (device preparation, setup and user) even though I do see the apps installed, all policies applied, the custom organization login before inputting my mail, everything. I even got the pre-provisioning screen when you press 5 times windows key. The device doesn’t appear under devices in Device Enrollment in Intune though and I also don’t see the AP icon next to it. Have you seen sth like this before? I will also test with another device too to be sure
Thank you
Hi Ian,
There has been a recent change at Microsoft which blocks JSON enrollment if you are blocking personal devices:
https://learn.microsoft.com/en-us/autopilot/existing-devices
Try unblocking personal enrollment and see what happens
Hi Andrew,
No, we have not yet blocked personal devices. I will try again with another device and let you know. Btw, in that case, wouldn’t json be redundant if someone has blocked personal devices?
And for context, I have been using the autopilot script for months now and it works every time, but I decided to start adding some safety around the secret (using keyvault) and that’s there where I saw a comment of yours in Reddit where you go over it, so I thought of trying the injection.
Thank you
Hi again,
Turns out the deployment profile is not applied. I do have a dynamic group to take i, but I assume it either doesn’t work as expected or can take time before intune sees i.
Thank you
Hi Andrew,
Update: Turns out I had a typo on the Profile ID in the dynamic rule… I will wait and let you know tomorrow if this fixes it.
Thank you for your answers (and the script) 🙂
Glad you sorted it 🙂
Hi Andrew,
Still didn’t work even though it appeared on the dynamic list after I used the user’s credentials to sign in. I will keep you updated. The getwindowsautopilot -online -addtogroup with some debloat scripts may remain as the way forward.
And for apps like McAfee returning after wipe/fresh start, I guess I can use the AutoPilot Reset.
Again thanks for all your scripts across your forums, replies in Reddit, etc 🙂
Hi Andrew,
I’m having some issues with the script since it does not download ISO with FIDO.
I get Server returned an error 403 forbiden. Any idea what might be cause of that?
Is there any option to use the script with ISO from VLSC and create iso with autopilot profile?
Thank you
Some times it’s the MS server running slowly. Often retrying in a few minutes fixes it.
Yes, you can use the -isopath parameter to use a pre-downloaded one
Hi,
Thank you for quick reply. As it looks like either there is a issue on script or our policy.
Since if I run the script it does not start downloading and never finish.
If I just run the Fido to download the iso I can do that.
Any idea?
Regards,
It launches Fido as a new PowerShell process, could you have something blocking that?
Does it create an output.txt file?
Hi,
everyone else having issues with new PowerShell 7.4.1 ?
With older Powershell 5 everything works great, and your script is amazing, thank you so much for it!
Thanks,
Daniel
Script Error Output:
Start-BitsTransfer: C:\Users\xxxxx\Dokumente\PowerShell\Scripts\create-windows-iso-with-apjson.ps1:539
Line |
539 | $download = Start-BitsTransfer -Source $windowsuri -Destination $isof …
| ~~~~~~~~~~~
| Cannot validate argument on parameter ‘Source’. The argument is null or empty. Provide an argument that is not
| null or empty, and then try the command again.
RuntimeException: C:\Users\xxxx\Dokumente\PowerShell\Scripts\create-windows-iso-with-apjson.ps1:541
Line |
541 | [int] $dlProgress = ($download.BytesTransferred / $download.Bytes …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Attempted to divide by zero.
RuntimeException: C:\Users\xxxxx\Dokumente\PowerShell\Scripts\create-windows-iso-with-apjson.ps1:541
Line |
541 | [int] $dlProgress = ($download.BytesTransferred / $download.Bytes …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Attempted to divide by zero.
RuntimeException: C:\Users\xxxxx\Dokumente\PowerShell\Scripts\create-windows-iso-with-apjson.ps1:541
Line |
I’m also running PS 7.4.1 and receiving the same error. Thanks for letting me know that this isn’t a problem with PS5. I’ll need to try on PowerShell 5.
I received the same error while using PS5.1, but I wasn’t concerned with the script finding the latest Windows ISO so I simply went back to the Aug2023 version of the script and manually put in the location of my ISO files and tweaked a couple variables.
For anyone interested, this URL shows the older version of the script. We can use this until the latest version is working on PS 7.4.1.
https://github.com/andrew-s-taylor/public/blob/a11d757c24e4732361f1d71e9f63492bffcbfd31/Powershell%20Scripts/Intune/create-windows-iso-with-apjson.ps1
It looks like an issue with invoke-expression in PS7. Will let you know when it is fixed
I’ve just added a new version which should hopefully fix it
It didn’t give me a reply button to your last question Andrew, so I created a new comment. Sorry. See my previous message. I don’t know when it times out because it doesn’t show much after we enter our credentials.
I’m not sure if this matters, but I did see this in powershell when it was creating the iso-
https://i.imgur.com/kGds4dg.png
I also used the isopath parameter with the Windows 11 Enterprise ISO that I previously downloaded.
I think this URL might have changed- “https://github.com/andrew-s-taylor/oscdimg/archive/main.zip”
It looks like this works-
https://github.com/andrew-s-taylor/oscdimg/archive/refs/heads/main.zip
The URL is working ok for me and that error isn’t anything to worry about.
Do you have a physical device you can test on to rule out something on VMWare? Or Hyper-V which I know works
I tried changing the URL and had the same result, so you’re right about that error being nothing to worry about. Okay I’ll try a physical machine and see if I have any luck.
I’m still getting the 80070002 error on a physical machine. I did make sure that we have deployment mode set to user-driven and convert all targeted devices to autopilot set to yes.
The autopilot device group should be set correctly- https://i.imgur.com/Y9Qtnq6.png
what did you mean by make sure you have mdm scopes set? Is there anything else I could be missing? I’m not sure what else to try.
Do devices enrolled using get-windowsautopilotinfo work?
After putting in credentials at the “Let’s set things up for your work or school” page (which has our company logo on it), it shows “Please wait while we setup your device…” and spins until it times out (I’m assuming).
Each time I try a new “DESKTOP-XXXXXXX” is added to our Autopilot device group that I added the dynamic membership rule to that you suggested (which seems positive). However, it doesn’t show up in Devices | Windows > Windows Enrollment > Windows Autopilot devices.
I imaged a VM with Windows 11 Enterprise iso that has our autopilot injected. I added the dynamic membership rule and I think it’s working because I’m seeing some members of the group that have the name “DESKTOP-XXXXXXX”. But when I go to windows enrollment > windows autopilot > devices, I do not see the device.
Everything looks good and I’m asked to sign in to autopilot. Then after 60 minutes it times out and shows “Something went wrong. Confirm you are using the correct sign-in information and that your organization uses this feature. You can try to do this again or contact your system administrator with the error code 80070002.”
Do you have any ideas?
They wouldn’t appear in Autopilot devices until after enrollment (as long as you have convert existing devices enabled).
Are MDM scopes set correctly and the users licensed for Intune?
Sorry about the other message. Thanks for replying.
Our ESP has scope tags set to default. I am testing as myself and I have an E5 license. AutoPilot has worked for me with Windows 10 devices before. This is my first time trying with a Windows 11 device and I am using a vsphere VM. Everything looks like it is going to work fine but it eventually times out with the error I stated earlier.
Ah, first things I would check:
1) Make sure you are using user enrolled, not self-deploying
2) Make sure your VM has TPM enabled
Yes we are using user enrolled.
I first tried a solution to add the tpm bypass in the registry and that let the installation continue (until it got this error).
I have since rebuilt the vm and added a TPM the correct way and Windows 11 installed without any errors (until it timed out after signing in with my company credentials)
What point during the ESP did it time-out?
Does this script grab the app list and install them? Is it possible to do that for a full offline installation?
No, this just enrols the device into Autopilot. There is no offline installation for Autopilot/Intune
I see, can this method download all the software that have been configured as part of autopilot profile?
No, it will only enrol into Autopilot. Software downloads during OOBE
Hello Andrew
Thank you for your cool script!
As we use Windows Enterprise and we have our ISOs already downloaded, it would be cool to have a switch in the script to pass the path of the ISO in the file system instead of downloading it every time we start the script.
Then the problem, that Enterprise version is not available in the version list also would be solved.
Thank you!
Hi Günther,
That’s a great idea, I’ve just uploaded a new version with “isopath” parameter
Thanks
Andrew
Hello Andrew
Thank you for the fast response.
I tested the script sucessfully.
Working great, but when using the isopath parameter it would make sense to not delete the source ISO file.
Good point, added to 3.0.5 so it skips that step
I keep these errors any passible solution?
Error: Cannot convert value “–” to type “System.Byte”. Error: “Value was either too large or too small for an unsigned byte.”
Downloading OS ISO
Start-BitsTransfer: C:\Scripts\AutoPilot_ISO.ps1:530
Line |
530 | $download = Start-BitsTransfer -Source $windowsuri -Destination $isof …
| ~~~~~~~~~~~
| Cannot validate argument on parameter ‘Source’. The argument is null or empty. Provide an argument that is not
| null or empty, and then try the command again.
RuntimeException: C:\Scripts\AutoPilot_ISO.ps1:532
Line |
532 | [int] $dlProgress = ($download.BytesTransferred / $download.Bytes …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| Attempted to divide by zero.
RuntimeException: C:\Scripts\AutoPilot_ISO.ps1:532
Line |
532 | [int] $dlProgress = ($download.BytesTransferred / $download.Bytes …
Can you confirm which OS and language you ave selected so I can test?
Windows 10 22h2
Eng-US
It seems to work ok for me, can you try now? Sometimes the URL generation times out which may have caused the issue
Yes wen through OOBE but don’t think it displayed the Autopilot ESP. But no not listed in Intune devices.
Did it prompt for login on OOBE?
Make sure your ESP is assigned correctly
I may have missed something. It works and shows on Entra ID as Entra ID Joined but isn’t on Intune. Any clues?
Did it go through OOBE and display the Autopilot ESP?
Is it just not listed anywhere in Intune devices?
Hello,
Mine is stuck on dismounting WIM and applying JSON…
any tips what the issue could be?
Also I see the folders created under C:\Temp but I cant delete them as they seem to be used somehow by another process
Hi,
Are you running in an elevated PowerShell? Dismounting can take a while, is there a progress bar?
Thank you Andrew for this excellent work.
It works fine now.
Version 3.0.1 works for me.
Thanks Andrew!
I see the same the same behavior when I mount the install.wim manually. The JSON does not contain all options and the Autopilot does not run as expected.
“CloudAssignedDeviceName”: null,
“ZtdCorrelationId”: null,
“Comment_File”: “Profile “,
When I export the JSON manually it contains all values.
https://learn.microsoft.com/en-us/autopilot/tutorial/existing-devices/create-json-file
Can you try 3.0.1 and see if that’s any better?
The previous problems are solved.
I took the script apart to see where the problem arises that the sign does not appear in the OOBE screen after installation.
After checking the JSON file, the following values are not filled in (CloudAssignedDeviceName, Comment_File and ZtdCorrelationId)
Maybe you can run it yourself to see the outcome.
It looks like you hard coded the JSON, but that’s amending on the local machine, not on the ISO so I can’t see how that would work
You mean the percentages ?
Yes the still count and the whole other process suceeded.
When i try to boot the ISO with Hyper-V or a standalone PC, nothing happend.
I think the error messed up the ISO.
Are you running in an elevated console?
When i run the script i get the following error:
oscdimg.exe :
At C:\Program Files\WindowsPowerShell\Scripts\create-windows-iso-with-apjson.ps1:643 char:1
+ & “$path\oscdimg\oscdimg-main\oscdimg.exe” -b”$InstallImage\efi\micro …
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Does the counter still increase?
Thanks for your confirmation.
Just wanted to confirm the process will be as below.
Step 1 : Create the Autopilot image with JSON file injected.
Step 2 : Create a dynamic group as mentioned in this article.
Step 2 : Rebuild the PC with the autopilot .iso image and it allows the user to login normally during the initial set up.
Please let me know if there is any video or article which explins the build process.
Thanks
Yes, that’s correct.
Dean has a video using it here:
https://www.youtube.com/watch?v=fRhZ-VaaTRk
Thanks for the great post.
Does this applies to Hybrid Azure AD Domain Join profiles as well ?
Yes, it shouldn’t be a problem. Obviously the standard Hybrid requirements remain though
Thank you, always a good read on your blog and when I have the time i will read your book
Glad you find it useful, always happy to take suggestions on new posts as well 🙂
Is there anyway to implement group tags?
I know the hardware hash is not uploaded, but you can use convert all targets to Autopilot, but then adding the group tag becomes a manual step?
Not with JSON injection, but you could probably create a post-build script to implement Group Tags on devices if you wanted something a bit less hands-on
This is failing with the following error. I’m running it as admin as well:
Write-Progress : Cannot validate argument on parameter ‘PercentComplete’. The argument is null, empty, or an element of the argument collection contains a null value. Supply a collection that does not contain any null values and
then try the command again.
At C:\Program Files\WindowsPowerShell\Scripts\create-windows-iso-with-apjson.ps1:529 char:102
+ … le…” -Status “$dlProgress% Complete:” -PercentComplete $dlProgress;
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Write-Progress], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.WriteProgressCommand
Attempted to divide by zero.
At C:\Program Files\WindowsPowerShell\Scripts\create-windows-iso-with-apjson.ps1:528 char:5
+ [int] $dlProgress = ($download.BytesTransferred / $download.Bytes …
That sounds like the download itself is failing. It should display the URL it is using for download in the output, it’s worth checking that runs in your device
Hello,
Just tested V3 and it’s working as expected! Thank you for the quick fix and the cool tools!
Excellent, glad it is all working 🙂
Hello,
when we skip entering the product key the Windows version defaults to education and we are unable to upgrade from there. I have also tried to enter a product key when prompted and it states that it’s not compatible with the version that is installed. When using the media creation tool or using Rufus to download a Windows iso works without issue.
Can you try version 3? That should let you select the windows edition
Will this method work with shared PC mode and a different version of windows? ex. Windows 10 Education or Enterprise
Yes to shared mode, but not self-deploying mode.
I will look to add edition selection in v3 if that would be useful?
v3 just released which lets you select. It won’t include Enterprise as that’s a different download which is hidden behind VLSC, but it should do an in-place update
Thanks but how would it do an in-place update? Do you mean from the license the user has such as E3/E5? or do you mean a script to upgrade the version?
It won’t do an in-place, this is a rebuild from ISO
Hello,
Is there a way to have the program pull a different image? I just tried to use the tool and the image that it downloads does not accept our product keys and it also isn’t working with the key pulled from the bios. Is there a way I can use my own image or is there something i doing wrong?
Yes, edit line 522 and replace the variable with your URL
If you press enter product key later, does it detect from your M365 license?
It gave me all the correct values running the GET request in graph explorer.
I ran the autopilot section and got the output of the json. The json is missing ztdcorrelationID and CloudAssignedDeviceName.
It might be worth doing a GET request against this URL in Graph explorer to see if the result is the same:
https://graph.microsoft.com/beta/deviceManagement/windowsAutopilotDeploymentProfiles
Yeah, I looked at the JSON and the ‘ztdcorrelationID’ value and ‘cloudassigneddevicename’ are set to null. Whenever I download the JSON config manually, I get the correct configuration in the JSON. Is there anything I can do to fix this? Or can I add my locally downloaded JSON file to the ISO?
If you run the script in an editor and run just the Autopilot section, check it is populating ok there. It could be failing at that point
But how is assigning the esp to users only going to help? The naming convention from the autopilot still wont apply the name template because of this change?
If the autopilot assigment doesn’t matter, is something wrong with the json itself then?
Thanks for all the reponse.
Yes, it sounds like there is either an issue with your profile, or with the JSON it has downloaded and injected. Does the OOBE user login appear ok?
If it does, you could break out into a PowerShell window and inspect the JSON file
I tried to create a new VM with the ISO and wait to see if it would make a difference. The device is not populated in to the autopilot group. How is Azure AD going to know about the device, when it is not joined or registered to Azure AD?
I just dont understand how a new device that does not exist in Azure AD, will be populated into a dynamic group. I cant use the rule validation towards the device because it does not exist in Azure AD.
You could try assigning your ESP to users instead.
The autopilot assignment doesn’t matter.
It is using the functionality from SCCM
https://learn.microsoft.com/en-us/autopilot/existing-devices
Right, so from a fresh installed VM with the ISO, without any record in Azure AD. The device will still populate in to the group? Otherwise its always gonna populate after the ESP is finished.
Yes, thats right, the dynamic rule will grab the AzureAD object which exists pre-ESP
Hi!
I’ve managed to get the autopilot group populating the device into the group in a different tenant. However this happens after the ESP has run, and therefore the name template and privacy settings wont apply. Any tips on what to do here?
It’s Microsoft time, you need to wait for the dynamic rule to populate before you start OOBE
Hi!
Will testing this on a virtual machine work, or do you have to test on a physical device with windows already pre-installed?
Hi,
It should be fine on a VM, the only thing a VM can’t do is any profiles with self-deploying mode
Hi!
I’ve corrected the dynamic query but still face some issues:
1. The ESP runs fine but still does not apply the Device nametemplate and does not skip the privacy settings.
2. The devices are not populated to the corrected dynamic group.
Is there something wrong in the ISO, or anything specific i should look for to troubleshoot this?
this is the dynamic group: (device.devicePhysicalIDs -any (_ -contains “[ZTDid]”)) -or (device.enrollmentProfileName -eq “OfflineAutopilotprofile-56f88377-e152-4ebc-8be5-cc0b5ddc7c07”)
If the device is not populating into the group, that is why the ESP is failing. Try using the What-If tool in the dynamic rule builder. It might be worth checking if it is case sensitive to begin with
So the query should look like this?
(device.devicePhysicalIDs -any (_ -contains “[ZTDid]”)) -or (device.enrollmentProfileName -eq “nameofautopilotprofile-IDofAutopilotProfile)
No, it’s “OfflineAutopilotProfile-IDofAutopilotprofile”
Hi, i am having the same issue. Just to be clear the dynamic query should be this?
(device.devicePhysicalIDs -any (_ -contains “[ZTDid]”)) -or (device.enrollmentProfileName -eq “nameofautopilotprofile-IDofAutopilotProfile)
No, it’s “OfflineAutopilotProfile-IDofAutopilotprofile”
Hi Andrew!
Thanks for your reply!
Maybe it’s a silly question, but for what can I use the ISO if everything get downloaded from Intune?
It’s a quick way of importing devices into Autopilot without having to run the get-windowsautopilotinfo script during OOBE
I changed the dynamic query to this: (device.devicePhysicalIDs -any (_ -contains “[ZTDid]”)) -or (device.enrollmentProfileName -eq “56f88377-e152-4ebc-8be5-cc0b5ddc7c07”) and provisioned a new device. It still doesent populate any devices or applies the autopilot settings from the profile.
You’re missing “OfflineAutopilotprofile-” from the query. Try using the WhatIf in the dynamic group rules builder to see if it picks up the devices
Hi, i tried changing my autopilot assignment group to this dynamic query: (device.devicePhysicalIDs -any (_ -contains “[ZTDid]”)) -or (device.enrollmentProfileName -eq “TID001 Autopilot”). However it doesent seem to work. It does not apply the name template and skip language and privacy settings.
When trying to validate a device provisioned by the iso, towards the group it says: dynamic membership rule validation error: invalid characters found in the rule. Invalid characters in the rule: ”
I tried changing the query to (device.devicePhysicalIds -any (_ -contains “[ZTDid]”)) or (device.enrollmentProfileName -eq “TID001 Autopilot”). It doesent complain about invalid characters in the rule. But is unable to validate devices provisioned by the ISO.
Is there anything wrong with the assigments/dynamic queries?
There profile name needs to be whatever is displayed in the address bar when you click on the profile (ID):
device.enrollmentProfileName -eq "OfflineAutopilotprofile-IDHERE"
Hey Andrew!
The script works as expected and the iso is build properly.
But I have a few questions.
Do we need to import the device into autopilot first?
Can we install the iso offline and all things (including apps) are still get installed?
How do I know that the ESP is using the iso and not downloading the things from Intune?
To use the iso properly which settings should we activate or deactivate in Intune?
Thank you!
Hi,
No need to add to autopilot first. If you add a dynamic group based on the autopilot profile, you can assign that and convert all existing objects to Yes to get these listed in Autopilot.
You will need an internet connection for Autopilot to happen and the apps installed.
It still uses Intune to download everything, this just enrols into Autopilot
So since this script doesent upload the hardware hash, you cant have a dynamic group containing the query: (device.devicePhysicalIDs -any _ -contains “[ZTDId]”), to the autopilot profile? You would need a dynamic group containing all windows devices instead?
I tried provisioning a computer with this, but it didnt apply the name template, which i am assuming, is because the autopilot profile is assigned to a group with the dynamic query i listed above. Is this assumption correct? And the device only shows as an Azure AD device and not an autopilot device, is this also because of the assignment or is this expected behavior?
Hi,
You need to change the dynamic rule to grab offline enrolled devices:
(device.devicePhysicalIDs -any (_ -contains "[ZTDid]")) -or (device.enrollmentProfileName -eq "YOURPROFILEID")
Make sure you have Convert existing devices to Autopilot devices set to yes on your profile and that this group is assigned to it. Then they should also convert to Autopilot
actually, nothing applies. I have a typical Windows installation
During OOBE it might be worth checking the Autopilot JSON is present on the USB drive
Also check for any enrollment restrictions.
Does it get to the autopilot login page?
Hi,
In the deployment profile, I’ve set up automatic naming, and I’ve run the Powershell script again.
Unfortunately, the computer is still named DESKTOP-XXXXX
Here’s my deployment profile:
Out-of-box experience (OOBE)
Deployment mode: Self-Deploying (preview)
Join to Azure AD as : Azure AD joined
Language (Region) :French (France)
Automatically configure keyboard : Yes
Microsoft Software License Terms :Hide
Privacy settings : Hide
Hide change account options : Hide
User account type: Standard
Allow pre-provisioned deployment : No
Apply device name template :Yes
Enter a name: 23-%SERIAL%
Do the other settings in the profile apply or all they all missing?
Hi,
I am new in this and was wondering if I could add this to a usb and make it bootable, then try booting from usb everytime to leverage autopilot
Hi,
Yes, that should work fine
Hi,
The ISO download works again.
I was able to register a PC correctly from Microsoft AutoPilot.
Thanks for the script, but I have one last question. In my Autopilot Deployment Profile, I’ve set the device name to automatic after installing the PC via ISO, the PC has a default name of DESKTOP-XXXXX.
How can I resolve this?
In your Autopilot profile, set a naming convention, %SERIAL% is one I usually use. Then re-create the ISO with the amended profile
Hi Mate,
What if I manually reset a device on windows reset – provisioned via autopilot, after the reset, can the end user login with their credentials after the reset?
As long as the device is enrolled into Autopilot Devices, the user will be prompted to login and continue OOBE with Autopilot
Thanks Andrew
Hi Andrew,
Thank you for this great tutorial, however, you can provide more information on the following steps:
-Grabs the Windows Professional WIM from within in
-Mounts the WIM and injects the autopilot JSON
-Converts the new WIM to an ISO (using oscdimg)
-Cleans up everything but the ISO
Thanks a lot
Francois
Hi Francois,
Of course.
It uses Fido to find the URL for the Windows version selected
Then it uses mount-diskimage to mount it to a temporary location.
It grabs the install.wim from that location and uses mount-windowsimage to mount that.
The JSON is injected with a simple copy command
Then is dismounts (dismount-windowsimage)
Deletes the original install.wim and replaces with the new one (export-windowsimage)
It then downloads oscdimg which creates the ISO
At the end it deletes all temp files leaving just the ISO and Fido
Hope this helps. The script is fully commented if you want to see exactly what’s happening
Hi Andrew,
I tried to create a Win11 22H2 image but the ISO is always created without install.wim. Do you have any idea?
Hi,
Are you running PowerShell as admin? Dismounting the WIM may error if not
Very awesome. Thanks for putting this together Andrew!
Hope you find it useful 🙂
Hello,
I get this error when downloading the ISO?
Connected to Intune tenant
Selecting OS
Finding latest supported versions
Windows 11 22H2 Chosen
Downloading Fido
Fido Downloaded
Grabbing ISO URL
Error: We are unable to complete your request at this time. Some users, entities and locations are banned from using this service. For this reason, leveragi
ng anonymous or location hiding technologies when connecting to this service is not generally allowed. If you believe that you encountered this problem in e
rror, please try again. If the problem persists you may contact Microsoft Support – Contact Us page for assistance. Refer to message code 715-123130 and 32d
f09d1-9630-4566-84aa-b6b30187a952.
Downloading OS ISO
Start-BitsTransfer : Impossible de valider l’argument sur le paramètre «Source». L’argument est Null ou vide. Indiquez un argument qui n’est pas Null ou
vide et réessayez.
Hi,
Sometimes that happens with Fido, I think it’s something at the Microsoft side. If you try again a bit later, it normally starts working again
Hi Andrew,
When running your latest script, 1.0.4, I came across this error:
Attempted to divide by zero.
At C:\Program Files\WindowsPowerShell\Scripts\create-windows-iso-with-apjson.ps1:462 char:5
+ [int] $dlProgress = ($download.BytesTransferred / $download.Bytes
Any thoughts as to how I may be able to resolve this?
Thanks
Hi Joel,
That sounds like it didn’t find the ISO location. Can you check if it’s downloaded the fido.ps1 script into the temp directory it created?
I’m getting the same error. fido.ps1 is in the temp directory it created.
so I still need get hash from device first?
No, if you inject the JSON, the hash is not required. You may need to amend the dynamic rule on your autopilot devices group depending on how your have your ESP configured
https://learn.microsoft.com/en-us/autopilot/existing-devices
I just tested it on VM and actually same as normal iso…
and in the end I logged in with different tenant.
No errors while creating iso.
I thought that this iso would post hw hash to autopilot…
It doesn’t post the hash, it injects the Json directly into the iso