I use Powershell 5.1 and we often install modules from our internal module repository hosted on our on-prem Azure Artifacts (we use Azure DevOps Server 2019).
The problem is that it is very slow. Takes regularly over 10 seconds to load one module. And this is not the network, which is pretty fast. It is the Install-Module
internals.
I tried running Set-PSDebug -Trace 2
from within an Azure DevOps build in order to get line timestamps, but it is useless. For example, observe this output snippet:
2020-06-29T04:20:40.6944925Z DEBUG: 267+ switch ( >>>> $MsgID)
2020-06-29T04:20:40.6957451Z DEBUG: ! SET $switch = ''.
2020-06-29T04:20:40.6972578Z DEBUG: 290+ >>>> }
2020-06-29T04:20:40.6986528Z DEBUG: ! SET $switch = ''.
2020-06-29T04:20:40.6998323Z DEBUG: 232+ >>>> }
2020-06-29T04:20:48.3791151Z DEBUG: 220+ $script:PackageManagementInstallModuleMessageResolverScriptBlock = >>>> {
2020-06-29T04:20:48.3808676Z DEBUG: ! CALL function '<ScriptBlock>' (defined in file 'C:\Program
2020-06-29T04:20:48.3811147Z Files\WindowsPowerShell\Modules\PowerShellGet\1.0.0.1\PSModule.psm1')
2020-06-29T04:20:48.3822332Z DEBUG: 222+ >>>> $PackageTarget =
2020-06-29T04:20:48.3824673Z $LocalizedData.InstallModulewhatIfMessage
It show 8 seconds pause, but the place where it shows it does not make any sense.
So, my question is this - why is it so slow? Is there a way to profile it reliably?
EDIT 1
Have just installed PS Core 7 - the same lousy performance for Install-Module
. My version of PowershellGet is:
C:\> Get-Module PowershellGet | Select Version
Version
-------
2.2.4
C:\>
EDIT 2
Found this page - https://learn.microsoft.com/en-us/powershell/scripting/gallery/how-to/working-with-packages/manual-download?view=powershell-7 It explicitly warns against simulating Install-Module
with nuget, even though it explains how to do it. I would like to understand more about the implications of using nuget instead of Install-Module
, besides it working 5 times faster (on average).
EDIT 3
The modules are not signed. We are talking about our internal modules. But installing modules from PSGallery, like Az.Accounts
, Az.Storage
and Az.Sql
takes about the same time. When our build needs to make sure 5 modules are installed it takes easily a minute. On another note, Install-Module
is not concurrency safe, so when our builds were running it bare we were facing all kinds of weird errors. They went away when we introduced explicit named mutex around Install-Module
. Needless to say, it did not contribute to performance.
20 minutes to install Az.
The Install-Module uses the Name parameter to specify the PowerShellGet module. Install-Module downloads and installs the newest version of PowerShellGet into the current user's directory, $home\Documents\PowerShell\Modules .
June 14th, 2022 The PowerShell Gallery is down.
It is the nature of PowerShell that it is going to be slow. It's a scripting language running on .NET. It is slow to open a session because it has to start up .NET, figure out what OS you are running and where your modules are, etc. the first tab completion should be slow the first time and faster afterwards.
.SYNOPSIS High Performance Powershell Module Installation .DESCRIPTION This is a proof of concept for using the Powershell Gallery OData API and HTTPClient to parallel install packages It is also a demonstration of using async tasks in powershell appropriately. Who says powershell can't be fast?
It's a scripting language running on .NET. It is slow to open a session because it has to start up .NET, figure out what OS you are running and where your modules are, etc. the first tab completion should be slow the first time and faster afterwards. Bash is fast because it doesn't do anything.
While this doesn't answer your "why", you might like to look at JustinGrote's high performance Powershell Gallery Module Installer:
.SYNOPSIS
High Performance Powershell Module Installation
.DESCRIPTION
This is a proof of concept for using the Powershell Gallery OData
API and HTTPClient to parallel install packages
It is also a demonstration of using async tasks in powershell
appropriately. Who says powershell can't be fast?
This drastically reduces the bandwidth/load against Powershell
Gallery by only requesting the required data
It also handles dependencies (via Nuget), checks for existing
packages, and caches already downloaded packages
.NOTES
THIS IS NOT FOR PRODUCTION, it should be considered "Fragile" and
has very little error handling and type safety
It also doesn't generate the PowershellGet XML files currently, so
PowershellGet will see them as "External" modules
It is indeed much faster.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With