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

如何在不启动新的Powershell会话的情况下强制重新加载模块函数定义?

  •  0
  • mark  · 技术社区  · 6 年前

    我有一个模块,我叫它 xyz.ps.core . 导出一个函数- Get-PullRequestsFromCommitIds

    我修复了函数中的一个错误,重新发布了该模块,重新安装并重新导入了它,但该函数仍然引用了该模块的旧版本。

    C:\xyz\tip [master ≡]> Get-Command Get-PullRequestsFromCommitIds | ft -AutoSize
    
    CommandType Name                          Version     Source
    ----------- ----                          -------     ------
    Function    Get-PullRequestsFromCommitIds 1.0.19107.4 xyz.ps.core
    

    如您所见,函数来自版本 1.0.19107.4

    C:\xyz\tip [master ≡]> get-module xyz.ps.core | ft -AutoSize
    
    ModuleType Version     Name             ExportedCommands
    ---------- -------     ----             ----------------
    Manifest   1.0.19107.7 xyz.ps.core {Assert-ExtractionDestFolder, Assert-PullRequestMatchesFolder, Backup-Database, Connect-OctopusToTfs...}
    
    
    C:\xyz\tip [master ≡]> get-module xyz.ps.core -ListAvailable | ft -AutoSize
    
    
        Directory: C:\Users\mkharitonov\Documents\WindowsPowerShell\Modules
    
    
    ModuleType Version     Name             ExportedCommands
    ---------- -------     ----             ----------------
    Manifest   1.0.19107.7 xyz.PS.Core {Assert-ExtractionDestFolder, Assert-PullRequestMatchesFolder, Backup-Database, Connect-OctopusToTfs...}
    

    1.0.19107.7 . 但是好吧,我有一个功能可以刷新模块,即使它已经安装到相同的版本:

    C:\xyz\tip [master ≡]> (get-command Use-Module).ScriptBlock
    param([Parameter(Mandatory)]$Name)
    
        if ($VerbosePreference -ne 'Continue')
        {
            Write-Host -ForegroundColor Cyan -NoNewline "Using the latest version of $Name ... "
        }
    
        Write-Verbose "Uninstalling all the versions of $Name ..."
        Uninstall-Module $Name -AllVersions -Force -ErrorAction SilentlyContinue
        Remove-Module $Name -Force -ErrorAction SilentlyContinue
    
        Write-Verbose "Installing the latest version of $Name ..."
        Install-Module $Name -Scope CurrentUser -Force
    
        Write-Verbose "Importing $Name into the current session ..."
        Import-Module $Name -Force
    
        if ($VerbosePreference -ne 'Continue')
        {
            Write-Host -ForegroundColor Cyan (Get-Module $Name).Version
        }
    

    现在让我们使用它:

    C:\xyz\tip [master ≡]> use-module xyz.ps.core
    Using the latest version of xyz.ps.core ... 1.0.19107.7
    

    C: \xyz\tip[master]>Get命令Get PullRequestsFromCommitIds | ft-AutoSize
    
    CommandType名称版本源
    函数Get PullRequestsFromCommitIds 1.0.19107.4xyz.ps.核心
    

    还是那个旧的。请注意,在一个新的Powershell窗口中,该函数取自当前版本的模块。

    0 回复  |  直到 6 年前
        1
  •  2
  •   HAL9256    6 年前

    行为就是一切 about scopes . TLDR:

    会话、模块和嵌套提示是自包含的环境,

    基本上,由于模块是自包含的环境,而不是子范围,所以它们不能将模块导入“父”脚本范围。 即使 你用 -Force

    sampleModule.psm1

    Function Test-Import { 
    param([Parameter(Mandatory)]$Name)
        Write-Host "List Loaded modules before"
        Get-Module
    
        Write-Host "Importing $Name into the current session ..."
        Import-Module $Name -Force
    
        Write-Host "Module Version $((Get-Module $Name).Version)"
    
        Write-Host "Loaded Modules After"
        #List Loaded modules after
        Get-Module
    }
    
    #Only present desired functions
    Export-ModuleMember -Function Test-Import
    

    如果我们从一个简单的空白测试开始(为了简洁起见,我删除了无关的模块):

    PS C:> #Clean state - Nothing Loaded for demonstration
    PS C:> Get-Module
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    
    PS C:> Import-Module .\sampleModule.psm1
    PS C:> Get-Module
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Script     0.0        Test-Module                         {Test-Import}
    
    PS C:> Test-Import ActiveDirectory
    List Loaded modules before
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Script     0.0        Test-Module                         {Test-Import}
    
    Importing ActiveDirectory into the current session ...
    Module Version 1.0.1.0
    
    Loaded Modules After
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Manifest   1.0.1.0    ActiveDirectory                     {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-ADFineGrainedPasswordPolicySubject...}
    Script     0.0        Test-Module                         {Test-Import}      
    

    这里我们注意到ActiveDirectory模块并没有出现在函数的开头,而是在函数的末尾被加载,并且报告了正确的版本。现在让我们看看它是否加载:

    PS C:> Get-Module
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Script     0.0        Test-Module                         {Test-Import}
    

    正如我们所看到的,由于模块在自己的自包含环境中运行,所以我们成功地将模块(本例中的ActiveDirectory)导入到模块作用域中,但没有像您预期的那样导入本地范围。

    解决这个范围问题的唯一方法是将模块导入全局范围 -Global 比如:

    Import-Module $Name -Force -Global
    

    在示例脚本中更改这一行,然后重新导入:

    PS C:> Import-Module .\sampleModule.psm1 -Force
    
    PS C:> Get-Module
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Script     0.0        Test-Module                         {Test-Import}
    
    PS C:> Test-Import ActiveDirectory
    List Loaded modules before
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Script     0.0        Test-Module                         {Test-Import}
    
    Importing ActiveDirectory into the current session ...
    Module Version 1.0.1.0
    
    Loaded Modules After
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Manifest   1.0.1.0    ActiveDirectory                     {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-ADFineGrainedPasswordPolicySubject...}
    Script     0.0        Test-Module                         {Test-Import}      
    

    和以前一样。。。现在让我们检查它是否正确加载:

    PS C:> Get-Module
    
    ModuleType Version    Name                                ExportedCommands
    ---------- -------    ----                                ----------------
    Manifest   1.0.1.0    ActiveDirectory                     {Add-ADCentralAccessPolicyMember, Add-ADComputerServiceAccount, Add-ADDomainControllerPasswordReplicationPolicy, Add-ADFineGrainedPasswordPolicySubject...}
    Script     0.0        Test-Module                         {Test-Import}