2014-10-08 62 views
6

如果我使用嵌套模块创建了清单模块,则在第一个模块之后的所有嵌套模块中导出的函数不会出现在可用命令列表中,不会触发模块自动加载。在脚本模块中调用嵌套模块中的函数并不总是触发模块自动加载

当我运行“Get-Module-ListAvailable”时,它们也不会出现。

只有从第一个嵌套模块导出的函数出现在命令列表中。

如果我明确导入模块,则所有导出的函数都可用。

在下面的示例中,Update-LegacyServices在显式导入模块之前不可用。

我可以使它工作的唯一方法是将我的模块文件重命名为以ps1而不是psm1结尾,并将它们包含在ScriptsToProcess中,这似乎是一个糟糕的主意。

模块清单(PSD1)

@{ 

# Script module or binary module file associated with this manifest. 
# RootModule = '' 

# Version number of this module. 
ModuleVersion = '1.0.0.1' 

# ID used to uniquely identify this module 
GUID = 'c11d6aca-d531-4d06-a732-5fb95113357f' 

# Author of this module 
Author = 'luke' 

# Company or vendor of this module 
CompanyName = '' 

# Copyright statement for this module 
Copyright = '' 

# Description of the functionality provided by this module 
# Description = 'MyBudget Developer Powershell Module' 

# Minimum version of the Windows PowerShell engine required by this module 
PowerShellVersion = '4.0' 

# Name of the Windows PowerShell host required by this module 
# PowerShellHostName = '' 

# Minimum version of the Windows PowerShell host required by this module 
# PowerShellHostVersion = '' 

# Minimum version of the .NET Framework required by this module 
DotNetFrameworkVersion = '4.5.0' 

# Minimum version of the common language runtime (CLR) required by this module 
CLRVersion = '4.0.30319.18444' 

# Processor architecture (None, X86, Amd64) required by this module 
# ProcessorArchitecture = '' 

# Modules that must be imported into the global environment prior to importing this module 
RequiredModules = 'BitsTransfer' 

# Assemblies that must be loaded prior to importing this module 
# RequiredAssemblies = @() 

# Script files (.ps1) that are run in the caller's environment prior to importing this module. 
ScriptsToProcess = @() 

# Type files (.ps1xml) to be loaded when importing this module 
# TypesToProcess = @() 

# Format files (.ps1xml) to be loaded when importing this module 
# FormatsToProcess = @() 

# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess 
NestedModules = @('database\Database.psm1', 'build\Build.psm1') 

# Functions to export from this module 
#FunctionsToExport = '*' 

# Cmdlets to export from this module 
CmdletsToExport = '*' 

# Variables to export from this module 
VariablesToExport = '*' 

# Aliases to export from this module 
AliasesToExport = '*' 

# List of all modules packaged with this module. 
ModuleList = @('database\Database.psm1', 'build\Build.psm1') 

# List of all files packaged with this module 
# FileList = @() 

# Private data to pass to the module specified in RootModule/ModuleToProcess 
# PrivateData = '' 

# HelpInfo URI of this module 
# HelpInfoURI = '' 

# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. 
# DefaultCommandPrefix = '' 

} 

模块1(构建\ Build.psm1)

function Update-LegacyServices() 
{ 
    echo "Update" 
} 

Export-ModuleMember -Function Update-LegacyServices 

模块2(数据库\ Database.psm1)

Function Get-Backup($directory, $name) 
{ 
    echo "Get-Backup" 
} 

Export-ModuleMember -Function Get-Backup 
+0

我想你必须从模块清单中取消注释'#FunctionsToExport ='*''。 – 2014-10-08 07:29:43

+0

你认为还是你测试过?对我而言都没有效果 – LukeN 2014-10-08 07:37:48

+0

正如我所说,我想。只是一种预感。如果它不起作用,那就这样吧。 – 2014-10-08 07:42:25

回答

3

我有这个线在我的.psd1文件

FunctionsToExport = 'FuncFromMainPsm1 FuncFromSecondPsm1' 

这是我从Powershell的工具Visual Studio生成的行推断:

# Functions to export from this module 
FunctionsToExport = '*' 

这引起了我的Get-Module -ListAvailable显示什么样子正确的事

Script  1.0  MyMModule     FuncFromMainPsm1 FuncFromSecondPsm1 

但是,当我叫FuncFromSecondPsm1我会得到“术语‘FuncFromSecondPsm1’不是......”。

所以我改变了我的出口线

FunctionsToExport = @('FuncFromMainPsm1', 'FuncFromSecondPsm1') 

现在,这一切的作品。我可以在我的模块加载后调用这两个函数,无论是通过自动加载还是Import-Module

我试过这个有和没有ModuleListFileList集合。他们没有区别。

+0

这对我的Module Module工作正常=脚本。我有ModuleType = Manifest的另一个模块,它不工作!需要更多调查 – 2015-06-04 02:16:45

+1

确认:在这种情况下,您似乎需要使用脚本清单。将其中一个脚本设置为根模块,然后其他脚本可以是嵌套模块。标记为根模块的模块与所有其他模块之间没有明显差异。 – 2015-06-04 02:22:52

1

海兰保罗,海兰Luken,

挣扎了几个小时就这个话题(与含蓄,并宣布清单的方法)后,我选择了自动生成的清单。 从本质上讲,我写了一个PS1脚本生成清单,分两个步骤:

  1. 一些“业务”的逻辑,发现要公开
  2. 生成模块清单什么

恕我直言,这种方法的优势:我'充分'了解和掌握模块内容的曝光。

下面你可以找到一个PS代码片段,遵循这种方法,希望它会受益于其他人。

# module discovery 
$rootModule = "WdCore"; 
$modules = Get-ChildItem *.psm1; 
$nestedmodulesNames = $modules | where { $_.BaseName -ne "WdCore"} | % { $_.BaseName } ; 

# functions discovery 
$modulesLines = $modules | Get-Content; 
$functionsLines = $modulesLines | where { $_.contains("Function") }; 

$functionNamePattern = '^Function\s+(?<name>([a-z][0-9|A-Z|-]+))\s?{.*$'; 
$functionNames = $functionsLines | where { $_ -match $functionNamePattern } | select { $Matches['name'] } | % { $_.' $Matches[''name''] '}; 

# generate manifest 
New-ModuleManifest ` 
    -Path ./WdTools.psd1 -RootModule $rootModule ` 
    -ModuleVersion '1.0' ` 
    -NestedModules $nestedmodulesNames ` 
    -FunctionsToExport $functionNames ` 
    -Guid '57D7F213-2316-4786-8D8A-3E4B9262B1E5' ` 
    -Author 'Blaise Braye' ` 
    -Description 'This module provides working directory tooling' ` 
    -PowerShellVersion '3.0' -ClrVersion '4.0';