我在目录中创建了一个自定义 powershell 模块
C:\Program Files\WindowsPowerShell\Modules\PennoniAppManagement。每当我对模块中的函数进行更改,然后将模块导入到脚本中时,更新的代码都不会生效。有什么解决办法吗?
确保在重新导入之前从会话中删除已加载的模块版本:
Remove-Module PennoniAppManagement -Force
Import-Module PennoniAppManagement
Run Code Online (Sandbox Code Playgroud)
通常,它本身就足以强制将更新的模块重新加载到当前会话中。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)