Powershell模块中* .psm1文件的用途是什么? [英] What is the purpose of the *.psm1 files in a Powershell module?

查看:1113
本文介绍了Powershell模块中* .psm1文件的用途是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我实现了我的第一个Powershell模块,其中包含一堆.ps1文件(每个功能一个)和.psd1清单文件.

我试图了解.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"
        }
    }
}

就像我说的那样,每个函数都在自己的文件中.

解决方案

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

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

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

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

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

  • 即使您在NestedModules清单条目中列出常规的*.ps1脚本,由于使用该特定条目,这些脚本还是在模块的上下文,从而成为模块的一部分 :

    • 从概念上讲,这等效于在RootModule中创建和引用根*.psm1脚本,并且-而不是定义NestedModules条目-显式地从点源化*.ps1脚本-参见底部.

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


列出NesteModules中的*.ps1文件与从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 
}

如果您需要按特定顺序加载脚本,只需要脚本的一个子集,或者想要稍微加快速度(尽管我怀疑速度差异会很明显),则可以对文件进行点源处理分别从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"

同样,以上所有方法在功能上都是等效的. 假设您通过ExportedFunctions条目显式导出了函数(建议),必须使用点源文件的*.ps1文件最终是与命令发现和模块自动执行目的无关的实现细节.正在加载-仅在实际导入时才重要.

So I implemented my first Powershell module with a bunch of .ps1 files (one per function) and the .psd1 manifest file.

I am trying to understand what is the purpose of the .psm1 files - do I need them at all in my module?

What is their added value?

EDIT 1

Here is my .psd1 file:

@{
    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"
        }
    }
}

Like I said, each function is in its own file.

解决方案

what is the purpose of the .psm1 files - do I need them at all in my module?

  • In script modules, i.e., modules authored in PowerShell (as opposed to compiled binary cmdlets), it is only *.psm1 files that provide the module-specific behaviors distinct from regular *.ps1 script files (separate, isolated scope, private commands, control over exported commands).

    • Typically, a script module manifest has a RootModule entry pointing to (the main) *.psm1 file; for smaller modules it is not uncommon for all of the module's functionality to be implemented in this one *.psm1 file.

      • In fact, a stand-alone *.psm1 file can also act as a module, though it doesn't integrate with PowerShell's module auto-discovery and auto-loading feature.

      • Note that if you were to use a regular *.ps1 script directly in RootModule, its definitions would be loaded into the caller's scope, not the module's; that is, you would lose the benefits of a module.

  • Even though you're listing regular *.ps1 scripts in your NestedModules manifest entry, by virtue of using that specific entry these scripts are dot-sourced in the module's context and thereby become part of the module:

    • This is conceptually equivalent to creating and referencing a root *.psm1 script in RootModule, and - instead of defining a NestedModules entry - explicitly dot-sourcing your *.ps1 scripts from there - see bottom section.

    • Note that if you were to reference *.psm1 files in NestedModules, they would truly become nested modules, with their own scopes; a nested module is usable from the enclosing module, but not visible to the outside world (though you can list it among the loaded modules with Get-Module -All).


Listing *.ps1 files in NesteModules vs. dot-sourcing them from the RootModule

While there should be no difference in functionality, using a *.psm1 RootModule to dot-source the *.ps1 files containing your module's functions can potentially simplify things, if you simply need to dot-source all *.ps1 files located in your module directory's subtree:

# 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 
}

If you need to load the scripts in a specific order, need only a subset of the scripts, or want to speed things up slightly (though I doubt that the speed difference will be noticeable), you can dot-source the files individually from a RootModule *.psm1 file, as an alternative to listing them in the NestedModules entry:

# 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"

Again, all of the above approaches are functionally equivalent. Given that you explicitly export functions via the ExportedFunctions entry (as is advisable), the use of *.ps1 files that must be dot-sourced is ultimately an implementation detail that is not relevant for the purposes of command discovery and module auto-loading - it only matters at actual import time.

这篇关于Powershell模块中* .psm1文件的用途是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆