Speeding up Win32 apps upload via PowerShell

For those of you following me on social media, you know that I for the past two months or so have been researching how Intune could be used to deploy large applications. While this post covers how to decrease the time it takes to upload the applications, you can read the initial post below:

Deploying Large Applications using Microsoft Intune

Upload options

Uploading Win32 applications can be done via the MEM portal, or via PowerShell and Microsoft Graph. And even within PowerShell you can choose between using Invoke-WebRequest commands or using azcopy.exe.

The Key to Success

What I found worked best for me, was to use a VM in Azure capable of supporting these large uploads. During my initial benchmarking tests, the way I ran the upload code consumed a lot of memory, forcing me to use a pretty beefy Azure VM instance (Standard E8-4s v3 instance which has 4 vCPUs and 64 GB RAM. Later than the road, after changing how the tests were run, I only needed a Standard_D2s_v3 instance with 2 vCPUs and 8 GB RAM. I also tested with a Windows 365 Cloud PC with 16 GB RAM, and that worked great too.

Note #1: While the Azure VM itself had about 2 Gbit/s upload speed to Internet according to Speedtest, uploads to Intune would not use all that bandwidth. In my tests I got between 30-140 mbit/s depending on upload method.

Uploaded speed according to Speedtest.

Note #2: Upload speeds may also vary depending on time of the day. During my testing I often managed to get about twice the upload speed during the night, compared to normal business hours for the region of our Intune tenant.

Note #3: Uploading via code selection (F8) in PowerShell ISE and VS Code turned out to be a real memory hog (up to 60 GB RAM used). Thanks @ncbrady for pointing me in the right direction and test uploads via powershell.exe as well. Running the scripts directly in a Windows PowerShell prompt only used up a few hundred MB which is perfectly OK.

VS Code using up a decent chunk of memory 🙂

Benchmarking the Uploads

Below you find the results from my testing. For the PowerShell testing I used the IntuneWin32App PowerShell module from @NickolajA, as well as the azcopy.exe fork of that module from @schenardie.

All tests were done from my Azure VM instance, and I was uploading an Intune package of the Adobe Suite 2022 which was 20.4 GB in size.

Test #1 – Upload via the MEM Portal

Uploading directly via the MEM portal is obviously a manual process. But if you are only creating a few applications, it's not too bad. I included this test for comparison, and here is the result:

  • Upload time: 35 minutes

Test #2 – Upload via IntuneWin32App PowerShell module – Different Chunk Sizes

When using the IntuneWin32App PowerShell module with various chunk sizes, I got the following results:

  • Upload time with 6 MB chunk size (default): 1 hours and 12 minutes
  • Upload time with 64 MB chunk size: 59 minutes
  • Upload time with 100 MB chunk size (maximum): 54 minutes

Note #1: If you try to go above 100 MB chunk size you'll be greeted with an error: The remote server returned an error: (413) The request body is too large and exceeds the maximum permissible limit. Ask me how I know 🙂

Note #2: The above differences may not sound like a big deal, but if you are uploading from a slower link, with higher latency, a 100 MB chunk size vs. a 6 MB chunk size can reduce the upload from 11 hours to 5 hours.

Test #3 – Upload via AzCopy edition (fork) of the IntuneWin32App PowerShell module

When using the IntuneWin32App PowerShell module fork from @schenardie, the upload is done via azcopy.exe, which is pretty fast for uploading stuff to Azure. I got the following results:

  • Upload time: 26 minutes
About the author

Johan Arwidmark

4.7 3 votes
Article Rating
Notify of
Inline Feedbacks
View all comments