Powershell模块设计 - Export-ModuleMember

Mat*_*w S 7 powershell function 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
Run Code Online (Sandbox Code Playgroud)

然后我将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模块的正常方面吗?

Sta*_*ing 18

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

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

你可以写:

Export-ModuleMember -Function a,b,c
Run Code Online (Sandbox Code Playgroud)

它导出一些功能.

要么

Export-ModuleMember -Function *
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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