PowerShell GUI for Downloading Windows 10/11 ESD images - W10_11aria2ESD.ps1

garlin

Moderator
Staff member
Messages
7,083
Reaction score
3,511
I've written a PowerShell GUI to download complete Win 10 & 11 ESD images. After recent changes, MS doesn't allow you to use their website to directly download ISO's for older W10 or 11 images. This affects downloaders like Rufus, TechBench and heidoc.net which required that backdoor.

While you can use MCT to download older releases with a wrapper, those images are dynamically created and not static files (for checksum comparison). For a current ISO image, continue to use the normal Microsoft Software Download websites.

This script allows you to select the RTM/GA or a more recent build, and uses a copy of aria2.exe to perform the actual ESD download. Using aria2, a normal download might only take about 6-8 min. to finish compared to much longer times using native PS methods.

Capture.PNG

What versions of Windows are supported?
  • Win 7 & 8.1 with WMF 5.1
  • Win 10 & 11
Why do I get a PowerShell execution policy error?
Your default execution policy prevents unsigned scripts from running. Run the W10_11aria2ESD.bat instead.

What Windows releases are available?
W10 1903 to 22H2 (x86, x64 & arm64), and W11 21H2 to 22H2 (x64 & arm64). For Home, Pro and EDU releases pick the Consumer Client, and Business for Enterprise VL editions. There is a government-approved China edition for local users.

Why does it need to run aria2?
aria2 is an open source tool which runs parallel network connections to dramatically speed up downloads. I'm using the same settings as UUP dump's download script for optimal performance.

How do I use the image?
NTLite can directly open the ESD image, and convert it back into an ISO format for processing. Or use abbodi86's ESD Decrypter tool, outside of NTLite. ESD compressed images are highly compact, so extraction may take several minutes.

Why don't I see Build nnnnn.nnnn listed?
MS doesn't provide every build in ESD format, so it's more like MCT in tracking the re-released ISO versions.

Why can't I find the download URL's in your script?
To write my script, I ransacked abbodi's pastebin collection, which is a set of long download URL's for every available release. The original lists are lengthy because there's multiple architectures and languages. The total line count for just the URL's was over 4200 lines!

Rather than separate data into another file (which creates the possibility of user error), I used .NET data compression to convert the lists into a character-encoded byte array and decompress it when the script runs. If you want, use Expand-Data.ps1 to verify its contents.

Can I restart a cancelled download?
If you cancel a download, and restart the same ESD file -- Aria2 will resume where it stopped, and continue downloading until done.
 

Attachments

Last edited:
Tested and download the file less than a minute. With the verifications of the download, I could say that the download was completed in 2-3 minutes. Great job!
 
Updated script with UI enhancements:
- Versions & Languages are listed in tabbed columns, for easier reading.
- Added W11 23H2 release (22631.2428)
 
Getting an error:
PS C:\Users\mreid\Downloads\W10_11aria2ESD> .\W10_11aria2ESD.ps1
Exception setting "LastWriteTime": "Cannot convert the "System.String[]" value of type "System.String[]" to type "System.DateTime"."
Start-Process: C:\Users\mreid\Downloads\W10_11aria2ESD\W10_11aria2ESD.ps1:1750
Line |
1750 | Start-Process "$PSScriptRoot\aria2c.exe" -Argument "-x16 -s16 -c -R $ …
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| This command cannot be run due to the error: An error occurred trying to start process
| 'C:\Users\mreid\Downloads\W10_11aria2ESD\aria2c.exe' with working directory
| 'C:\Users\mreid\Downloads\W10_11aria2ESD'. The system cannot find the file specified.
 
getting this error:

Get-Variable : Cannot find a variable with the name '26100.2033'.
At C:\Users\user\Downloads\W10_11aria2ESD\W10_11aria2ESD.ps1:1772 char:13
+ $URL = (Get-Variable -Name $Build).Value | Where { $_ -like "*$($ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (26100.2033:String) [Get-Variable], ItemNotFoundException
+ FullyQualifiedErrorId : VariableNotFound,Microsoft.PowerShell.Commands.GetVariableCommand
 
Wow. That was totally broken, which is unexpected since I normally test the script every time it gets updated.

My bad, dunno why $ReleaseTable's Build column globally swapped "_" with "." I've uploaded the corrected version.
Code:
$ReleaseTable = ConvertFrom-Csv @'
    Build,       Release
    26100_2033,  "26100.2033 W11 24H2 (Oct 2024)"
    26100_1742,  "26100.1742 W11 24H2 GA"
    22631_2861,  "22631.2861 W11 22H2 (Dec 2023)"
...
    17763_1,     "17763.1         W10 1809 RTM"
'@

intelfx, thanks for the aria2c tweaks but for simplicity I try to just duplicate what UUP dump does for their Aria calls. Not because it's the best possible options, but it's "no better or worse" than what they do.

UPDATE: This is lame, 22631 was incorrectly labeled 22H2 (and not 23H2). So much inattention to detail :mad:.
 
Last edited:
can i just change the names on line 1536 & 7 to say 23H2 or would that mess things up for the download?
 
can i just change the names on line 1536 & 7 to say 23H2 or would that mess things up for the download?
Whenever Windows is released (or updated) in ESD format, there's a list of 181 or 262 download URL's corresponding to the different language & architecture editions. W11 is 64-bit only, so there's half as many versions as for W10 (dual architecture).

The individual URL's are ridiculously long. For example:
Code:
http://dl.delivery.mp.microsoft.com/filestreamingservice/files/b558c2aa-62fa-4a81-9581-e8e7f4300a85/26100.2033.241004-2336.ge_release_svc_refresh_CLIENTBUSINESS
_VOL_x64FRE_ar-sa.esd
http://dl.delivery.mp.microsoft.com/filestreamingservice/files/be0b8a2e-e28a-4af4-b547-09419daa723d/26100.2033.241004-2336.ge_release_svc_refresh_CLIENTBUSINESS
_VOL_x64FRE_bg-bg.esd
http://dl.delivery.mp.microsoft.com/filestreamingservice/files/06cd812c-735e-45b4-b1b7-1364eb7efa43/26100.2033.241004-2336.ge_release_svc_refresh_CLIENTBUSINESS
_VOL_x64FRE_cs-cz.esd
http://dl.delivery.mp.microsoft.com/filestreamingservice/files/c57c8725-fccc-4348-82d7-22bb75a3cb2f/26100.2033.241004-2336.ge_release_svc_refresh_CLIENTBUSINESS
_VOL_x64FRE_da-dk.esd

If you compiled a full list of the ESD versions I have gathered for the script, the URL's alone would be over 800KB. There's even more Windows builds that exist, but I choose to only keep the official RTM or GA build, and the latest one.

No one wants to read a 5000+ line script. So I take a set of collected files (copies of abbodi86's pastebins), and use a compression function to create an encoded binary object. What you see as the encoded object is uncompressed back into run-time memory. This makes it much more manageable. If you wanted to browse the raw tables, a link to Expand-Data.ps1 is provided in post #1.

The final step is to convert a top-level list of which builds are included, and provide their release names. Unless you're a modding geek, most users can't remember W10 19042 is 20H2. While my auto-generator script created the list, but I have to manually add the description notes.

In short, you can't really edit $Release_Table other than to remove lines to hide editions you don't care about. $Release_Table is simply an index back to the uncompressed URL tables. For simplicity, I didn't want to separate the list into an external data file (because someone will try editing it and break the script).

Hope that makes sense.
 
would be incredidle to add check boxes(and appropriate scripting) to combine things.

eg: ability to select multiple languages and it would create an multilague image.
 
would be incredidle to add check boxes(and appropriate scripting) to combine things.

eg: ability to select multiple languages and it would create an multilague image.
There's no feature for selecting multiple images, because I'm running aria2c to perform the actual download. Even on a high-speed connection, it may take a few minutes for each ISO to download. I didn't want to kill your PC.

The point of this script is to find older Windows builds (in ESD format) which are no longer offered as ISO's or by the Media Creation Tool. You can't combine different ESD images to build a multi-language ISO. It doesn't work that way.

An ISO of any base language can have additional Language Packs applied as Updates.

1. For updating an image with a handful of languages, use this script to download Languages Packs (multi-selection is supported):
PowerShell GUI for Downloading Language Packs - W10_11LangPack.ps1

2. If you need to add many languages at the same time, it's more useful to download the specific Languages and Optional Features (LSOF) ISO for your Windows release. LSOF has all of the 22 Language Packs in one ISO, so you don't need to download them individually.
PowerShell GUI for Downloading Windows ADK, WinPE, LP & FOD ISO's - W10_11ADK_WinPE_LP_FOD.ps1
 
Back
Top