代码之家  ›  专栏  ›  技术社区  ›  FBryant87

导入多个版本的Powershell模块会全部加载吗?

  •  1
  • FBryant87  · 技术社区  · 4 年前

    导入多个版本的模块(这是PS7):

    Import-Module -Name MyModule -RequiredVersion 1.0.28
    Import-Module -Name MyModule -RequiredVersion 1.0.29
    

    将两个版本加载到您的会话中:

    Get-Module -Name MyModule 
    

    输出:

    ModuleType Version    PreRelease Name
    ---------- -------    ---------- ---- 
    Script     1.0.28                MyModule
    Script     1.0.29                MyModule
    

    当您尝试编写CI/CD脚本时,这会变得非常令人困惑,因为有人可能在本地加载了多个版本。就我而言,我想确保在继续之前加载了特定版本。

    在这种情况下,PS实际使用的是哪个版本?它是最后加载的版本,而不是最高版本?

    除了循环所有其他版本并将其删除之外,是否有一种简单的方法来确保使用特定版本?

    1 回复  |  直到 4 年前
        1
  •  10
  •   mklement0    2 年前

    在这种情况下,PS实际使用的是哪个版本?

    这个 最近进口的 版本优先 ,其输出 Get-Module 表示在 颠倒 优先顺序(自PowerShell Core 7.2.0-preview.5起);也就是说, 这个 最后的 列出的版本 获取模块 给定模块的输出是实际输出 (对于同名命令)。

    对于给定 命令 ,您可以使用 Get-Command 查看它来自哪个模块(版本)。 1.

    注意事项 :最新导入的版本仅在阴影的意义上具有优先权 同名命令 从以前导入的版本。因此,如果以前导入的版本 额外的 最近导入的版本(不再)定义的命令,它们仍然有效。


    除了循环所有其他版本并将其删除之外,是否有一种简单的方法来确保使用特定版本?

    如果要确保不加载其他版本,请使用 Remove-Module <name> ,其中 删除 全部的 模块的版本 使用会话中的给定名称。

    相比之下, 如果你想卸载一个 具体的 版本 ,你会通过一个 完全限定的模块名称 Remove-Module s -FullyQualifiedName 参数;例如。:

    Remove-Module -FullyQualifiedName @{ ModuleName = 'MyModule'; RequiredVersion = '1.0.28' }
    

    注意使用 RequiredVersion 键指定 准确的 要卸载的版本;相比之下,使用按键 ModuleVersion 将卸载给定版本 以及所有更高的 .

    另请注意:

    • 如所述 Cpt.Whale's helpful answer :

      • 请参阅下面的自动加载模块注意事项 .
      • 您同样可以使用 -全名 -RequiredVersion 具有 Import-Module 用于特定版本的导入。
      • 您可以选择导入 有选择地 即a 子集 使用 -Cmdlet , -Function , -Alias -Variable 参数。
        • 注:使用 任何 这些参数的值意味着您必须明确指定 全部的 您要导入的导出,跨相关参数;例如,如果你使用 -Alias @() 为了有效 排除 从导入导出别名,您还必须使用 -Cmdlet / -功能 参数,用于指定您要使用的cmdlets/函数 想要进口;但是,您可以使用 -Cmdlet * / -Function * 选择它们全部。
    • 注意事项re auto-loading modules -即放置在以下目录之一中的那些 $env:PSModulePath ,按原样 典型的 :

      • 如果您已删除某个模块的所有版本 移除模块 但至少有一个版本是自动加载的,使用其导出的任何命令稍后都会触发其(重新)导入,所有导出都会被导入。

      • 同样,如果您导入了一个特定版本的模块,并且同一模块的(不同)版本(也)自动加载,则使用导出的命令 仅限于后者 触发后者的自动加载,从而 隐式地隐藏那些与原始导入的特定版本同名的导出

      • 如果你使用过,发生这种情况的风险就会增加 -Cmdlet , -功能 , -别名 -变量 对于 选择性 导入最初导入的特定版本,因为然后使用任何 非进口 自动加载版本中也存在的导出会触发后者的自动加载。

      • 一个简单的例子:假设您手动导入版本 1.0 模块 Foo 为了加载 Get-Foo cmdlet( Import-Module Foo -RequiredVersion 1.0 ). 但是,自动加载版本 Foo 是版本 2.0 ,并且还有一个 Set-Foo 命令。当你打电话的时候 设置Foo 稍后,版本 2 隐含地 (自动)导入,以及 它的 获取Foo 现在,实现会隐藏最初导入的实现 1 版本 Foo .


    [1] 请注意,您甚至可以获得当前 阴影 命令,通过其特定的模块版本使用 -FullyQualifiedModule 参数(例如。
    Get-Command Get-Foo -FullyQualifiedModule @{ ModuleName='Foo'; RequiredVersion='1.0.28' }
    ),然后您可以使用调用 & ,the call operator 。但是,由于中详述的错误 GitHub issue #15298 ,自PowerShell Core 7.2.0-preview.5起生效,仅当目标模块版本为 明确导入 首先(例如。, Import-Module Foo -RequiredVersion 1.0.28 ).

        2
  •  3
  •   Cpt.Whale    4 年前

    在mkelement0的精彩答案中添加更多我遇到困难的细节:

    • Get-Module 返回以下列表 ExportedFunctions , ExportedCmdlets ,以及 ExportedCommands 对于每个加载的模块版本。太好了!

    • 警惕嵌套模块!Powershell将分离命名模块的信息,并在 NestedModules 你要的那个人的财产。

    • 您可以在执行以下操作时指定哪些命令和模块版本 import-module ,这可以让您更好地管理运行环境,而不仅仅是一次导入整个模块。

    示例:

    # Here I have two versions loaded, but only one has any exported cmdlets:
    Get-Module ExchangeOnlineManagement | Format-List Version,ExportedFunctions,ExportedCmdlets,ExportedCommands,NestedModules
    
    Version           : 2.0.4
    ExportedFunctions : {[Connect-ExchangeOnline, Connect-ExchangeOnline], …}
    ExportedCmdlets   : {[Get-EXOCasMailbox, Get-EXOCasMailbox], …}
    ExportedCommands  : {[Get-EXOCasMailbox, Get-EXOCasMailbox], …}
    NestedModules     : {Microsoft.Exchange.Management.RestApiClient,
                        Microsoft.Exchange.Management.ExoPowershellGalleryModule}
    
    Version           : 2.0.5
    ExportedFunctions : {[Connect-ExchangeOnline, Connect-ExchangeOnline], …}
    ExportedCmdlets   : {}
    ExportedCommands  : {[Connect-ExchangeOnline, Connect-ExchangeOnline], …}
    NestedModules     : {}
    
    # I can see function Connect-ExchangeOnline was loaded twice, so to see which version is active:
    Get-Command Connect-ExchangeOnline 
    
    CommandType : Function
    Name        : Connect-ExchangeOnline
    Version     : 2.0.5
    Source      : ExchangeOnlineManagement
    
    # I use this to see current loaded assemblies, and module version should be in the path
    [appdomain]::CurrentDomain.GetAssemblies() |
        Where { $_.Modules.FullyQualifiedName.contains('ExchangeOnlineManagement') } |
        Select -ExpandProperty Modules |
        Format-List Name,Assembly,FullyQualifiedName
    
    Name               : Microsoft.Exchange.Management.AdminApiProvider.dll
    Assembly           : Microsoft.Exchange.Management.AdminApiProvider, Version=17.0.0.0
    FullyQualifiedName : \path\to\Modules\ExchangeOnlineManagement\2.0.4\netCore\Microsoft.Exch 
                         ange.Management.AdminApiProvider.dll
    
    Name               : Microsoft.Exchange.Management.ExoPowershellGalleryModule.dll
    Assembly           : Microsoft.Exchange.Management.ExoPowershellGalleryModule, Version=17.0.0.0
    FullyQualifiedName : \path\to\Modules\ExchangeOnlineManagement\2.0.4\netCore\Microsoft.Exch 
                         ange.Management.ExoPowershellGalleryModule.dll
    
    
    推荐文章