首页 > 解决方案 > 为什么 Powershell 的 Install-Module 速度如此之慢?

问题描述

我使用 Powershell 5.1,我们经常从托管在本地 Azure Artifacts 上的内部模块存储库安装模块(我们使用 Azure DevOps Server 2019)。

问题是它非常慢。加载一个模块通常需要超过 10 秒。这不是网络,它非常快。它是Install-Module内部结构。

我尝试Set-PSDebug -Trace 2从 Azure DevOps 构建中运行以获取行时间戳,但它没有用。例如,观察这个输出片段:

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

它显示8秒暂停,但它显示的地方没有任何意义。

所以,我的问题是——为什么这么慢?有没有办法可靠地分析它?

编辑 1

刚刚安装了 PS Core 7——同样糟糕的性能Install-Module。我的 PowershellGet 版本是:

C:\> Get-Module PowershellGet | Select Version

Version
-------
2.2.4

C:\>

编辑 2

找到此页面 - https://docs.microsoft.com/en-us/powershell/scripting/gallery/how-to/working-with-packages/manual-download?view=powershell-7它明确警告不要Install-Module使用 nuget进行模拟,即使它解释了如何做到这一点。我想更多地了解使用 nuget 而不是 的含义Install-Module,除了它的工作速度快 5 倍(平均)。

编辑 3

模块未签名。我们正在谈论我们的内部模块。但是从 PSGallery 安装模块,比如Az.AccountsAz.StorageAz.Sql需要大约相同的时间。当我们的构建需要确保安装了 5 个模块时,只需一分钟。另一方面,Install-Module并​​发不是安全的,所以当我们的构建裸运行时,我们面临着各种奇怪的错误。当我们在周围引入显式命名互斥​​锁时,它们就消失了Install-Module。不用说,它对性能没有贡献。

标签: powershellmodule

解决方案


虽然这不能回答您的“为什么”,但您可能想看看 JustinGrote 的高性能 Powershell Gallery 模块安装程序

.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

它确实快得多。


推荐阅读