Powershell模块设计 - Export-ModuleMember

时间:2014-03-05 17:39:58

标签: function powershell powershell-module

我正在构建一个模块,用于导出我想通过我的个人资料提供的cmdlet。此cmdlet的实现分布在多个实现文件中,这些文件包含我不想公开的实现函数。所以我使用Export-ModuleMember来隐藏它们。

get_something.psm1

import-module .\get_something_impl.psm1

function Get-Something {
    [cmdletbinding()]
    Get-SomethingImplementation
}

Export-ModuleMember -Function Get-Something

然后我将get_something.psm1添加到我的个人资料中。通过仅导出Get-Something,我的所有实现功能都保持“私有”。

我遇到的问题是,当使用Export-ModuleMember命令时,每次我需要一个函数时,我必须在我的实现文件中导入一个模块。例如,假设我有一个模块person.psm1,其中包含我需要在所有实现文件中调用的函数Get-Person。现在我必须在每个需要调用Get-Person的文件中导入person.psm1。这是使用Export-ModuleMember -Function Get-Something的结果。没有它,我只需要导入person.psm1一次,它就可用了。

从本质上讲,Export-ModuleMember不仅阻止了我的外部实现,而且还阻止了我自己的实现。

这是否是预期并被认为是设计Powershell模块的正常方面?

1 个答案:

答案 0 :(得分:17)

在模块开发过程中,这实际上是一个争论。最初,Export-ModuleMember需要导出任何功能。这变得乏味和限制。因此,默认情况下,只要您从未在.PSM1中使用过Export-ModuleMember,模块中的所有函数都是可见的,但变量和别名不可见。

如果您使用Export-ModuleMember,它将开始限制该列表。导出少量函数可能不是一个坏主意,但你必须小心使用它。

你可以写:

Export-ModuleMember -Function a,b,c

导出一些函数。

Export-ModuleMember -Function *

后者相当于完全省略Export-ModuleMember。

如果您愿意,可以使用限制性更强的通配符,但我发现99%的情况下,您根本不需要打扰它。

您似乎要问的另一件事是如何最好地处理模块依赖项。如今,在编写脚本时导入一个或两个模块是相当普遍的,就像在C#项目中包含一个或两个程序集相当普遍。如果您在模块内部执行此操作,则可以在Import-Module上使用-Global标志,并避免使用-Force(将重新加载模块)。这使得在不同功能中重用模块更有效。它还使得不太可能出现“循环”(卸载和重新加载)模块的问题,不幸的是,许多模块都做得不好。

在每个函数中引用模块的替代方法是使用模块清单(Get-Help New-ModuleManifest)。模块清单非常有趣,需要学习模块开发的许多部分。如果在模块清单的RequiredModules列表中包含模块,则会在导入模块之前自动加载该模块(至少在PowerShell 3及更高版本中)。如果在模块清单的NestedModules列表中包含一个模块,它将作为模块的一部分加载,模块导出的命令将由模块导出。

模块设计是一个棘手的野兽,但做正确的事情是非常有益的。祝你好运。