我创建了一个自定义 powershell .psm1 模块,但编辑后它不会更新

Dai*_*kyu 3 powershell module

我在目录中创建了一个自定义 powershell 模块
C:\Program Files\WindowsPowerShell\Modules\PennoniAppManagement。每当我对模块中的函数进行更改,然后将模块导入到脚本中时,更新的代码都不会生效。有什么解决办法吗?

Mat*_*sen 6

确保在重新导入之前从会话中删除已加载的模块版本:

Remove-Module PennoniAppManagement -Force
Import-Module PennoniAppManagement
Run Code Online (Sandbox Code Playgroud)

  • @mklement0 在模块开发过程中重新导入时,我在自定义类型/类的范围解析方面遇到了许多奇怪的情况,因此从 ~5.1 开始,`rmo -force;ipmo` 已经成为一种习惯。不知道OP是不是也有这样的经历…… (2认同)

mkl*_*nt0 5

  • 通常,它本身就足以强制更新的模块重新加载到当前会话中。Import-Module-Force

    • Import-Module -Force Remove-Module在重新加载模块之前隐式执行(如果当前未加载模块,-Force则仅正常加载模块)。

    • 另请注意,如果您通过语句加载模块(至少从 PowerShell 7.1.2 开始),则不能选择强制重新加载模块。using module值得注意的using module是,如果模块导出class调用者应该看到的自定义定义,则需要导入方法 - 有关详细信息,请参阅此答案

  • 在某些情况下显然需要马蒂亚斯的两步方法- Remove-Module -Force,然后是- ,并且在您的方法中似乎也是需要的。Import-Module

    • 最好了解何时需要采用两步法。Mathias 认为这与自定义定义的缓存版本class(在模块内部使用)的延迟有关,而不是在Import-Module -Force调用时重新加载和重新定义。也就是说,虽然整个模块可能会重新加载,但它可能会在陈旧的 class环境下运行。至少在下面的简单场景中,无论是在 Windows PowerShell 5.1 中还是在 PowerShell (Core) 7.2.1 中,我都无法重现此问题,但在某些情况下可能会出现问题。

    • Remove-Module文档仅将该参数描述为与已加载模块的模块信息对象上可用的(很少使用)属性-Force相关(您可以使用 检查它)。默认值为,允许随时卸载(移除)模块。如果属性值为,则需要卸载;如果是,则该模块一旦加载就根本无法从会话中删除 - 至少不能使用..AccessMode(Get-Module ...).AccessModeReadWriteReadOnlyRemove-Module -ForceConstantRemove-Module

      • 值得注意的是,发生的隐式Import-Module -Force卸载不受这些限制的约束,并且即使模块受限制也会隐式卸载模块(从 PowerShell 7.1.2 开始;我不清楚这是否是设计使然)。.AccessModeConstant

测试代码涉及重新加载具有修改后的定义的模块class,以查看是否Import-Module -Force足够:

# Create a template for the content of a sample script module.
# Note: The doubled { and } are needed for use of the string with
#       with the -f operator later.
$moduleContent = @'
class MyClass {{
  [string] $Foo{0}
}}

function Get-Foo {{
  # Print the property names of custom class [MyClass]
  [MyClass]::new().psobject.Properties.Name
}}
'@

# Create the module with property name .Foo1 in the [MyClass] class.
$moduleContent -f 1  > .\Foo.psm1

# Import the module and call Get-Foo to echo the property name.
Import-Module .\Foo.psm1; Get-Foo

# Now update the module on disk by changing the property name
# to .Foo2
$moduleContent -f 2  > .\Foo.psm1

# Force-import (reload) the module and 
# see if the property name changed.
Import-Module -Force .\Foo.psm1; Get-Foo

# Clean up.
Remove-Item .\Foo.psm1
Run Code Online (Sandbox Code Playgroud)

Windows PowerShell(最新版​​本是 v5.1)和PowerShell (Core) 7.2.1(截至撰写本文时的当前版本)中,上述结果如预期的那样:

Foo1  # Original import.
Foo2  # After modifying the class and force-reloading
Run Code Online (Sandbox Code Playgroud)