Powershell模块设计 - 导出 - 模块成员 [英] Powershell Module Design - Export-ModuleMember

查看:271
本文介绍了Powershell模块设计 - 导出 - 模块成员的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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


$ b

get_something.psm1



  import-module .\get_something_impl.psm1 

函数Get-Something {
[cmdletbinding()]
Get-SomethingImplementation
}

Export-ModuleMember -Function Get-Something

然后将get_something.psm1添加到我的配置文件中。通过仅导出Get-Something,我所有的实现函数都保持为private。

我遇到的问题是使用Export-ModuleMember命令时,必须每次我需要一个函数时,在我的实现文件中导入一个模块。例如,假设我有一个带有函数Get-Person的person.psm模块,我需要在所有实现文件中调用它。现在我必须在每个需要调用Get-Person的文件中导入person.psm1。这是使用Export-ModuleMember -Function Get-Something的结果。没有它,我只需要导入person.psm1一次,它就可以使用。实际上,Export-ModuleMember不仅阻止了我的实现,还阻止了我自己的实现。



这是预期的并且被认为是设计Powershell模块的一个正常方面吗? 这实际上是一个有争议的问题模块的开发。最初,Export-ModuleMember被要求导出任何函数。这变得乏味和限制。因此,默认情况下,模块中的所有函数都是可见的,但只要您从未在.PSM1中使用过Export-ModuleMember,变量和别名就不会显示。



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



您可以编写:

  Export-ModuleMember  - 函数a,b,c 

它导出了一些函数。

或者

  Export-ModuleMember -Function * 

后一个相当于省略了Export-ModuleMember。



如果您愿意,可以使用更多限制性的通配符,但我发现99%的时间,你根本不需要费心。 / p>

您似乎要问的另一件事是如何最好地处理模块依赖关系。现在,在编写脚本时导入一个或两个模块相当常见,就像在C#项目中包含一个或两个程序集相当常见一样。如果你在模块内部执行此操作,可以在Import-Module上使用-Global标志,并避免使用-Force(它将重新加载模块)。这使得在不同功能中重复使用模块更有效率。这也使它不太可能出现模块骑自行车(卸载和重新加载)的问题,不幸的是,许多模块不能很好地完成工作。

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



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


I am building a module that exports a cmdlet that I would like to make available through my profile. The implementation of this cmdlet is spread across multiple implementation files that contain implementation functions I don't want to make publicly available. So I use Export-ModuleMember to hide them.

get_something.psm1

import-module .\get_something_impl.psm1

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

Export-ModuleMember -Function Get-Something

I then add get_something.psm1 to my profile. By exporting only Get-Something all of my implementation functions remain "private".

The issue I'm experiencing is that when using the Export-ModuleMember command, I have to import a module in my implementation files every time I need a function inside of it. For example, assume I have a module person.psm1 with a function Get-Person that I need to call throughout all of my implementation files. Now I must import person.psm1 in every single file that I need to call Get-Person. This is a result of using Export-ModuleMember -Function Get-Something. Without it, I would only need to import person.psm1 once and it would be available.

In essence, Export-ModuleMember is not only blocking my implementation to the outside, it's blocking it from my own implementation.

Is this expected and considered a normal aspect of designing Powershell modules?

解决方案

This was actually a bit of debate during the development of modules. Originally, Export-ModuleMember was required to export any function. This became tedious and limiting. So, by default, all functions from a module are visible, but variables and aliases are not, as long as you've never used Export-ModuleMember within the .PSM1.

If you use Export-ModuleMember, it begins to restrict that list. It may not be a bad idea to export a smaller number of functions, but you have to use it somewhat carefully.

You can either write:

Export-ModuleMember -Function a,b,c

which exports a few functions.

or

Export-ModuleMember -Function *

The latter one is equivalent to omitting Export-ModuleMember altogether.

You can use more restrictive wildcards if you'd like, but I find that 99% of the time, you don't need to bother with it at all.

The other thing you seem to be asking is how best to handle module dependencies. Nowadays, it's fairly common to import a module or two when writing a script, just like it's fairly common to include an assembly or two in a C# project. If you're doing this inside of a module, you can use the -Global flag on Import-Module, and avoid using -Force (which will reload the module). This makes it a notch more efficient to reuse the module in different functions. It also makes it less likely to have problems with "cycling" (unloading and reloading) the module, which, unfortunately, many modules do not do well.

The alternative to referencing the module in each function is using a module manifest (Get-Help New-ModuleManifest). Module manifests are very interesting, and required learning for many parts of module development. If you include a module in the RequiredModules list of the Module manifest, it will be automatically loaded before the module is imported (at least in PowerShell 3 and greater). If you include a module in the NestedModules list of the module manifest, it will be loaded as part of the module, and the commands exported by the module will be exported by your module instead.

Module design is a tricky beast, but it's very rewarding to do right. Best of luck.

这篇关于Powershell模块设计 - 导出 - 模块成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆