我为此创建了一个PowerShell模块 MyUtil.psm1 和 list 文件 MyUtil.psd1 。在psd1文件中,已定义前缀,以防止导出函数的名称冲突:
DefaultCommandPrefix = 'MyToolbox'
这样,在运行
Import-Module .\MyUtil.psd1
之后,psm1文件中的类似于Get-Command
的函数将成为Get-MyToolboxCommand
,一切都很好。但是,如果有人运行 Import-Module .\MyUtil.psm1
直接导入psm1文件,则不会使用psd1文件,并且不会应用我想要的前缀。如果我想防止这种情况(直接导入MyUtil.psm1),有没有办法让仅允许导入相应的psd1 list 文件而不是psm1文件?或者以编程方式检测该模块未通过psd1导入,因此我可以警告用户使用psd1?
最佳答案
好的,这有点烦人,但是可以。您可以使用不带参数的Export-ModuleMember cmdlet来阻止psm1导出任何内容,但是在导入过程中需要将psd1中的值发送到psm1。这样我们就知道何时被psd1调用。因此,首先,在PSD中的PrivateData哈希表中添加一个值:
PrivateData = @{
FromPSD = $true
PSData = @{
然后,您需要在psm1文件中访问它。您可以在函数中,但不能内联,因此我们必须将其粘贴到函数中。
function Get-PD
{
[CmdletBinding()]
$MyInvocation.MyCommand.Module.PrivateData
}
(我从这个SO答案Accessing PrivateData during Import-Module完全偷走了这个)。
然后,通过在模块中调用此代码将其包装起来,该代码将在加载模块时运行。
$MyPD = Get-PD
if($MyPD.Count -eq 0)
{
Export-ModuleMember
}
现在,如果您不希望在加载模块时引用此令人讨厌的额外功能,则需要在psd1文件中的“FunctionsToExport”中填充希望用户访问的功能列表。