从脚本模块中的嵌套模块调用函数并不总是触发模块自动加载

时间:2014-10-08 06:54:00

标签: powershell

如果我使用嵌套模块创建清单模块,则第一个嵌套模块中的导出函数不会出现在可用命令列表中,也不会触发模块自动加载。

当我运行“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 \ Build.psm1)

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

Export-ModuleMember -Function Update-LegacyServices

第2单元(database \ Database.psm1)

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

Export-ModuleMember -Function Get-Backup

2 个答案:

答案 0 :(得分:3)

我的.psd1文件中有这一行

FunctionsToExport = 'FuncFromMainPsm1 FuncFromSecondPsm1'

这是我从Powershell Tools for 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时都尝试过此操作。他们没有任何区别。

答案 1 :(得分:1)

Hy Paul,Hy Luken,

在这个主题上挣扎了几个小时(使用隐式和声明的清单方法)后,我选择了自动生成的清单。 本质上,我写了一个生成清单的ps1脚本,分两步:

  1. 与一些' business'逻辑,发现你想要揭露的内容
  2. 生成模块清单
  3. 恕我直言,这种方法的优点:我完全'理解并掌握模块内容的曝光。

    下面你可以找到一个遵循这种方法的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';