iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article
😎

Drastically Speeding Up Invoke-WebRequest

に公開

TL;DR

  • I want to speed up Invoke-WebRequest.
  • Since it just involves sandwiching the command between $ProgressPreference = 'SilentlyContinue' and $ProgressPreference = 'Continue', there are almost no side effects.
  • It becomes overwhelmingly fast, so you should definitely use this on Windows Server where PowerShell 5.1 is commonly used.

Introduction

Invoke-WebRequest is often used in automation scenarios, such as downloading .msi or .exe files using PowerShell and then executing them with msiexec.
However, to put it bluntly, it is quite slow, and I always felt that downloading through a browser was much faster.
Upon investigating, I found that disabling the progress bar can dramatically speed up the process.

Note that this applies to PowerShell 5.1; version 7 is not slow to begin with.

PS C:\Users\ikko\Downloads> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.22621.3880
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.22621.3880
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Before Speedup

I will try downloading the AVD RDAgent msi.
When running Invoke-WebRequest normally, it takes about 20 seconds.

PS C:\Users\ikko\Downloads> Measure-Command { Invoke-WebRequest -Uri https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrmXv -OutFile .\Microsoft.RDInfra.RDAgent.Installer-x64.msi; Remove-Item .\Microsoft.RDInfra.RDAgent.Installer-x64.msi }


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 20    <<<<<<<< This means 20 seconds
Milliseconds      : 95
Ticks             : 200958357
TotalDays         : 0.000232590690972222
TotalHours        : 0.00558217658333333
TotalMinutes      : 0.334930595
TotalSeconds      : 20.0958357
TotalMilliseconds : 20095.8357

After Speedup

Add $ProgressPreference = 'SilentlyContinue' before Invoke-WebRequest and $ProgressPreference = 'Continue' after execution.
Just with this, it literally changes to finishing in seconds.

PS C:\Users\ikko\Downloads> Measure-Command { $ProgressPreference = 'SilentlyContinue'; Invoke-WebRequest -Uri https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWrmXv -OutFile .\Microsoft.RDInfra.RDAgent.Installer-x64.msi; Remove-Item .\Microsoft.RDInfra.RDAgent.Installer-x64.msi; $ProgressPreference = 'Continue' }


Days              : 0
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 446    <<<<<<<< This means 0.446 seconds
Ticks             : 4460986
TotalDays         : 5.16317824074074E-06
TotalHours        : 0.000123916277777778
TotalMinutes      : 0.00743497666666667
TotalSeconds      : 0.4460986
TotalMilliseconds : 446.0986

Summary

In this article, I introduced a way to speed up the frequently used Invoke-WebRequest. I was impressed by how much faster it becomes simply by hiding the progress bar.

References

  • amazon ec2 - Powershell - Why is Using Invoke-WebRequest Much Slower Than a Browser Download?

    A 9-year-old question, but the information is still valid and very helpful.

https://stackoverflow.com/questions/28682642/powershell-why-is-using-invoke-webrequest-much-slower-than-a-browser-download

  • Invoke-WebRequest (Microsoft.PowerShell.Utility) - PowerShell

https://learn.microsoft.com/powershell/module/microsoft.powershell.utility/invoke-webrequest?wt.mc_id=MVP_391314

Discussion