【问题标题】:Creating powershell modules from multiple files, referencing with module从多个文件创建powershell模块,引用模块
【发布时间】:2017-06-12 22:34:16
【问题描述】:

我使用单独的源文件创建了一个 PowerShell 脚本模块。从其他内部源文件引用模块内部源函数的规范方法是什么?

例如,如果我的模块是从文件“foo”和“bar”中的 PS 源代码创建的;并且“foo”中的函数需要调用“bar”中的函数,最好的方法是什么?

似乎点源不是一个好主意。也不制作组件文件(“foo”和“bar”)psm1 文件。这是 psd1 文件中“ScriptsToProcess”字段背后的想法吗?

我是否在考虑这个错误(非“PowerShelly”)?我应该将所有内容都转储到单个 psm1 中吗?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    我亲自遵循了 RamblingCookieMonster 在他的博客中提出的做法:http://ramblingcookiemonster.github.io/Building-A-PowerShell-Module/

    这是将您的函数组织到子文件夹\Public\Private 下的单独的.ps1 文件中。 Public 包含用户应该能够直接调用的函数,Private 用于仅由您的模块内部使用的函数。

    然后在 .psm1 文件中通过循环和点源加载函数,如下所示:

    #Get public and private function definition files.
        $Public  = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue )
        $Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue )
    
    #Dot source the files
        Foreach($import in @($Public + $Private))
        {
            Try
            {
                . $import.fullname
            }
            Catch
            {
                Write-Error -Message "Failed to import function $($import.fullname): $_"
            }
        }
    
    # Here I might...
        # Read in or create an initial config file and variable
        # Export Public functions ($Public.BaseName) for WIP modules
        # Set variables visible to the module and its functions only
    
    Export-ModuleMember -Function $Public.Basename
    

    您还应该在 .psd1 模块清单文件中的 FunctionsToExport 设置下明确列出您的公共函数名称。这样做可以让这些功能被发现,并在使用时自动加载模块。

    【讨论】:

    • 这是个好主意。我确实对这种结构有疑问。我有一个也使用数据文件的私有函数。我正在考虑为其他文件创建第三个文件夹,但是您如何从私有函数中调用它们?
    • 我可能会使用 .. 上一层然后到文件夹:. ..\data\file.psd1
    • 实际上,包含 $PSScriptRoot 以使其行为一致:$PSScriptRoot\..\Data\File.psd1
    【解决方案2】:

    由于我最近不得不自己做这件事,我正在分享我的解决方案。我最近开始在 psm1 文件中对函数进行分组。这些可以编译成具有单个清单的单个模块。

    这允许我拥有可以与多个模块一起打包的功能组。

    Write-BarFunctions.psm1

    Function Write-Bar {
      return "Bar"
    }
    
    Function Write-Baz {
        return "Baz"
    }
    

    Write-FooFunctions.psm1

    Function Write-Foo {
        return "Foo"
    }
    
    Function Write-FooBar {
        $foo = Write-Foo
        $bar = Write-Bar
        return ("{0}{1}" -f $foo, $bar)
    }
    
    Function Write-FooBarBaz {
        $foobar = Write-FooBar
        $baz = Write-Baz
        return ("{0}{1}" -f $foobar, $baz)
    }
    

    它们组合成一个模块,如下所示: (为便于阅读而格式化)

    New-ModuleManifest 
        -Path .\Write-FooBarBazCombos 
        -NestedModules @('.\FooFunctions\Write-FooFunctions.psm1', '.\BarFunctions\Write-BarFunctions.psm1') 
        -Guid (New-Guid) 
        -ModuleVersion '1.0.0.0' 
        -Description 'demonstrate multiple psm1 files as 1 powershell module with 1 powershell module manifest' 
        -PowerShellVersion $PSVersionTable.PSVersion.ToString() 
        -FunctionsToExport @('Write-Foo', 'Write-Bar','Write-FooBar', 'Write-FooBarBaz')
    
    
    

    PowerShell 输出:

    PS C:\LWC\scripting-misc\module-manifest-multiple-files-example> New-ModuleManifest -Path .\Write-FooBarBazCombos.psd1
    -NestedModules @('.\Write-FooFunctions.psm1', '.\Write-BarFunctions.psm1') -Guid (New-Guid) -ModuleVersion '1.0.0.0' -D
    escription 'demonstrate multiple psm1 files as 1 powershell module with 1 powershell module manifest' -PowerShellVersio
    n $PSVersionTable.PSVersion.ToString() -FunctionsToExport @('Write-Foo', 'Write-Bar','Write-FooBar', 'Write-FooBarBaz')
    
    PS C:\LWC\scripting-misc\module-manifest-multiple-files-example> Import-Module .\Write-FooBarBazCombos.psd1
    PS C:\LWC\scripting-misc\module-manifest-multiple-files-example> Get-Command -Module Write-FooBarBazCombos
    
    CommandType     Name                                               Version    Source
    -----------     ----                                               -------    ------
    Function        Write-Bar                                          1.0.0.0    Write-FooBarBazCombos
    Function        Write-Foo                                          1.0.0.0    Write-FooBarBazCombos
    Function        Write-FooBar                                       1.0.0.0    Write-FooBarBazCombos
    Function        Write-FooBarBaz                                    1.0.0.0    Write-FooBarBazCombos
    
    • 请注意,Write-Baz 未在导入的模块中公开,因为它已从 FunctionsToExport 参数中排除,因此 Write-FooBarBaz 会出错(有意显示行为)。
    PS C:\LWC\scripting-misc\module-manifest-multiple-files-example> Write-FooBar
    FooBar
    

    目录中剩下的内容:

    PS C:\LWC\scripting-misc\module-manifest-multiple-files-example> Get-ChildItem | Select-Object Name
    
    Name
    ----
    Write-BarFunctions.psm1
    Write-FooBarBazCombos.psd1
    Write-FooFunctions.psm1
    

    附录 - 我在另一个问题中扩展了这个答案 - 这里:

    https://stackoverflow.com/a/56171985/7710456

    【讨论】:

    • 这是写答案。注意不仅对Nested-Modules 的显式引用。还有FunctionsToExport.
    【解决方案3】:

    @瑞恩 我同样认为点源不是这里的最佳选择,但我不再那么确定了。我也使用了 NestedModules 方法,但是遇到了一个特定的问题。我在这里问过这个问题: PowerShell module, call function in NestedModule from another NestedModule

    总的来说,我发现 PrimaryModule 可以调用任何 NestedModule 中的任何函数。但是一个 NestedModule 不能调用另一个 NestedModule 中的函数。

    将代码拆分为多个逻辑文件是 Developer 101 的基础。所以我真的很惊讶没有标准的方法来处理这个问题。

    非常感谢这里的任何帮助。请阅读链接的问题,它提供了很多细节。必须使用点源是共识吗?因为我发现拆分代码的模块清单方式非常有限。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-07
      • 1970-01-01
      相关资源
      最近更新 更多