我正在创建一个模块,该模块依赖于我需要加载到全局环境中的其他几个模块。我尝试创建一个脚本并使用 ScriptsToProcess 导入模块,但看起来RequiredModules 的检查发生在 ScriptstoProcess 运行之前。
模块清单中是否有一种很好、干净的方式来要求一个模块并在它尚未加载的情况下自动加载它?如果无法加载模块,则RequiredModule 会抛出错误。
我正在创建一个模块,该模块依赖于我需要加载到全局环境中的其他几个模块。我尝试创建一个脚本并使用 ScriptsToProcess 导入模块,但看起来RequiredModules 的检查发生在 ScriptstoProcess 运行之前。
模块清单中是否有一种很好、干净的方式来要求一个模块并在它尚未加载的情况下自动加载它?如果无法加载模块,则RequiredModule 会抛出错误。
如果您要分发模块,这也是确保使用 PowerShellGet(即PowerShell Gallery )的人安装您的依赖项的唯一方法。
如果缺少所需的模块,它仍然会失败,但否则会完全按照您希望的方式工作。
在任何一种情况下,用户都可以通过键入手动加载需求Import-Module RequiredModule, YourModule
——如果已经导入,他们将不会获得第二个实例......
您也可以改为在 NestedModules 中指定模块。即使在 PowerShell 2 中,它们也会在您的模块“内部”加载,但在它们已经加载时似乎不会对资源产生负面影响。但是,正如@JasonMArcher 提醒我的那样,在 PowerShell 2 中,如果您的模块被卸载(通过 Remove-Module),NestedModules 会与您的模块一起被卸载,即使它们是由用户单独预加载的,也会发生这种情况,这最终会导致生成非常奇怪的错误报告,因为您的用户不会期望这样。
另一个适用于所有版本的 PowerShell的选项是在模块的顶部调用Import-Module
(在 psm1 脚本中,在检查以确保模块尚未加载之后),-ErrorAction Stop
这样模块的导入将失败如果依赖模块的导入失败。
if (!(Get-Module Dependency)) { ## Or check for the cmdlets you need
## Load it nested, and we'll automatically remove it during clean up
Import-Module Dependency -ErrorAction Stop
}
实际上,如果您想检查版本...
if (!(Get-Module Dependency | Where { $_.Version -ge "2.5" )) {
## Load version 2.5 (or newer), or die
Import-Module Dependency -Version 2.5 -ErrorAction Stop
}
请记住,这不是文档,因此如果您分发模块,您的用户将不会知道依赖关系。
PowerShell V3 的工作方式略有不同。现在,当您使用指定的键加载清单时会加载所需的模块。此外,删除模块不会卸载所需的模块,无论该模块是如何加载的。有趣的是, -Force 似乎没有显示所需模块的自动加载。
编辑:如果您的模块不在默认位置之一,则需要将该模块的路径(或模块所在的父文件夹)添加到$env:PSModulePath
变量中。
旁注:由于 PSv3 支持脚本#Requires
中的命令。您可以使用它来 (1) 尝试在脚本中加载模块依赖项,以及 (2) 如果模块未/无法加载则终止。
#Requires -Modules ModuleName1,ModuleName2
这还需要模块位于 下$env:PSModulePath
,必须在运行脚本之前设置。