我正在创建一个模块,该模块依赖于我需要加载到全局环境中的其他几个模块。我尝试创建一个脚本并使用ScriptsToProcess导入模块,但看起来在ScriptstoProcess运行之前检查RequiredModules。
在模块清单中是否有一个很好的,干净的方法来同时需要一个模块并在它尚未加载时自动加载它?如果无法加载模块,则RequiredModule将抛出错误。
答案 0 :(得分:9)
PowerShell V3的工作方式有所不同。现在,在加载指定了该键的清单时,将加载所需的模块。此外,无论该模块如何加载,删除模块都不会卸载所需的模块。有趣的是,-Force似乎没有显示所需模块的自动加载。
编辑:如果您的模块不在默认位置之一,则需要将该模块的路径(或模块所在的父文件夹)添加到$env:PSModulePath
变量。
附注:由于PSv3支持脚本中的#Requires
命令。您可以使用此方法(1)尝试在脚本中加载模块依赖项,以及(2)在模块未加载/无法加载时终止。
#Requires -Modules ModuleName1,ModuleName2
这也需要模块位于$env:PSModulePath
下的某个位置,必须在运行脚本之前设置。
答案 1 :(得分:8)
这也是确保人们使用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
}
请记住,这不会作为文档,因此如果您分发模块,您的用户将不会知道依赖项。