Powershell 模块中 *.psm1 文件的用途是什么?

mar*_*ark 6 powershell module

因此,我使用一堆.ps1文件(每个函数一个)和.psd1清单文件实现了我的第一个 Powershell 模块。

我试图了解这些.psm1文件的用途是什么 - 我的模块中是否需要它们?

它们的附加值是什么?

编辑1

这是我的.psd1文件:

@{
    ModuleVersion = "0.0.19106.59054"
    GUID = "59bc8fa6-b480-4226-9bcc-ec243102f3cc"
    Author = "..."
    CompanyName = "..."
    Copyright = "..."
    Description = "..."
    ScriptsToProcess = "vsts\config.ps1"
    VariablesToExport = @(
        "TfsInstanceUrl",
        "TfsApiVersion",
        "QANuGetRepoUrl"
    )
    NestedModules = @(
        "db\Backup-Database.ps1",
        ...
        "vsts\work\Get-WorkItems.ps1"
    )
    FunctionsToExport = @(
        "Assert-ExtractionDestFolder",
        ...
        "Write-HostIfNotVerbose"
    )
    PrivateData = @{
        PSData = @{
            ExternalModuleDependencies = "SqlServer"
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

就像我说的,每个函数都在它自己的文件中。

mkl*_*nt0 8

这些文件的用途是什么.psm1- 我的模块中是否需要它们?

  • 脚本模块中,即在 PowerShell 中编写的模块(与编译的二进制 cmdlet 相对),只有*.psm1文件提供与常规*.ps1脚本文件不同的特定于模块的行为(单独的、隔离的范围、私有命令、对导出命令的控制)。

    • 通常,脚本模块清单有一个RootModule指向(主)*.psm1文件的条目;对于较小的模块,在这个文件中实现模块的所有功能并不罕见*.psm1

      • 事实上,独立 *.psm1文件也可以充当模块,尽管它没有与 PowerShell 的模块自动发现和自动加载功能集成。

      • *.ps1请注意,如果您直接在 中使用常规脚本RootModule,则其定义将被加载到调用者的作用域中,而不是模块的作用域中;也就是说,您将失去模块的好处。

  • 尽管您*.ps1在清单条目中列出了常规脚本NestedModules,但通过使用该特定条目,这些脚本在模块的上下文中是点源的,从而成为模块的一部分

    • 从概念上讲,这相当于*.psm1在 中创建和引用根脚本RootModule,并且 - 而不是定义NestedModules条目 -从那里*.ps1显式点采购您的脚本- 请参阅底部部分。

    • 请注意,如果您要引用*.psm1中的文件NestedModules,它们将真正成为嵌套模块,具有自己的作用域;嵌套模块可从封闭模块中使用,但对外界不可见(尽管您可以使用 将其在加载的模块中Get-Module -All)。


列出*.ps1文件与NesteModules从以下位置获取文件RootModule

虽然功能上应该没有区别,但如果您只需要对位于模块目录子树中的所有*.psm1 RootModule文件进行点源,则使用点源包含模块函数的文件*.ps1可能会简化事情: *.ps1

# Add this to the *.psm1 file specified in 'RootModule'

# Find all *.ps1 files in the module's subtree and dot-source them
foreach ($script in 
  (Get-ChildItem -File -Recurse -LiteralPath $PSScriptRoot -Filter *.ps1)
) { 
  . $script 
}
Run Code Online (Sandbox Code Playgroud)

如果您需要按特定顺序加载脚本,只需要脚本的子集,或者想要稍微加快速度(尽管我怀疑速度差异会很明显),您可以从RootModule *.psm1文件,作为在条目中列出它们的替代方法NestedModules

# Add this to the *.psm1 file specified in 'RootModule'

# Dot-source the *.ps1 files individually.
. "$PSScriptRoot/db/Backup-Database.ps1"
# ...
. "$PSScriptRoot/vsts/work/Get-WorkItems.ps1"
Run Code Online (Sandbox Code Playgroud)

同样,上述所有方法在功能上都是等效的。鉴于您通过条目显式导出函数ExportedFunctions(建议这样做),使用*.ps1必须是点源的文件最终是一个实现细节,与命令发现和模块自动加载的目的无关 - 它只在以下情况下重要:实际导入时间。