10

我正在创建一个模块,该模块依赖于我需要加载到全局环境中的其他几个模块。我尝试创建一个脚本并使用 ScriptsToProcess 导入模块,但看起来RequiredModules 的检查发生在 ScriptstoProcess 运行之前。

模块清单中是否有一种很好、干净的方式来要求一个模块并在它尚未加载的情况下自动加载它?如果无法加载模块,则RequiredModule 会抛出错误。

4

2 回答 2

10

在 PowerShell 3 及更高版本中,RequiredModules自动加载

如果您要分发模块,这也是确保使用 PowerShellGet(即PowerShell Gallery )的人安装您的依赖项的唯一方法。

如果缺少所需的模块,它仍然会失败,但否则会完全按照您希望的方式工作。

在 PowerShell 2 中,无法自动加载 RequiredModules

在任何一种情况下,用户都可以通过键入手动加载需求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
}

请记住,这不是文档,因此如果您分发模块,您的用户将不会知道依赖关系。

于 2011-03-30T18:08:36.273 回答
10

PowerShell V3 的工作方式略有不同。现在,当您使用指定的键加载清单时会加载所需的模块。此外,删除模块不会卸载所需的模块,无论该模块是如何加载的。有趣的是, -Force 似乎没有显示所需模块的自动加载。


编辑:如果您的模块不在默认位置之一,则需要将该模块的路径(或模块所在的父文件夹)添加到$env:PSModulePath变量中。


旁注:由于 PSv3 支持脚本#Requires中的命令。您可以使用它来 (1) 尝试在脚本中加载模块依赖项,以及 (2) 如果模块未/无法加载则终止。

#Requires -Modules ModuleName1,ModuleName2

这还需要模块位于 下$env:PSModulePath,必须在运行脚本之前设置。

于 2012-05-10T15:45:38.073 回答