自动加载cmdlet作为模块的一部分



所以,我在想:我有很多(!)自定义cmdlet,但我不希望它们在我的配置文件中加载所有的cmdlet,因为,自然地,这将花费很多时间。(我工作很快,所以我的工具也需要很快。)但我也不想总是手动加载,因为那样很烦人。(再一次……我工作很快!)

幸运的是,有一个简洁的功能叫做"自动加载"。这就完全解决了我的问题…种。我只需要把我的cmdlet放入脚本模块中,它们就会自动加载,对吧?

似乎需要满足一些要求,PowerShell才能"检测"到。属于某个模块的cmdlet。到目前为止,我所知道的最简单的方法是简单地将每个cmdlet放在单个ps1文件中,然后创建一个清单,如下所示:

@{
ModuleVersion = "1.0"
NestedModules = @(
"Get-Something.ps1",
"Remove-Something.ps1",
"Test-Something.ps1",
"Run-Something.ps1",
"Invoke-Something.ps1",
"Start-Something.ps1",
"Stop-Something.ps1"
),
CmdletsToExport = @(
"Get-Something",
"Remove-Something",
"Test-Something",
"Run-Something",
"Invoke-Something",
"Start-Something",
"Stop-Something"
)
}

这确实有效。但就像我说的…我工作很快,而且我很懒。如果模块可以动态地发现它的成员,那就容易多了。基本上,所有ps1文件都在同一个文件夹中。使用psm1文件中的一些代码,这将非常容易地工作。但是,自动加载将无法工作。我知道PowerShell确实需要事先知道导出的cmdlet。

除了在psd1模块清单中显式指定它们之外,还有其他动态方法可以做到这一点吗?

如果您担心模块的大小或组织,可以为cmdlet的不同公共主题创建不同的模块,并将每个模块的函数放入psm1中。然后确保将cmdlet定义添加到模块清单(psd1)中的CmdletsToExport。如果您有一个集中式提要,那么分发模块就变得很容易,如果您只是想在给定的时间内获得所有模块,那么您可以创建一个顶级模块,将其他模块列为依赖项,以便在安装顶级模块时安装它们。除非您有数百到数千个cmdlet作为单个模块的一部分导出,否则您不需要担心性能问题。

对于您在PSModulePath上的每个模块,如果您不想逐个名称导出它们,您可以在清单的CmdletsToExportFunctionsToExport部分中使用通配符来自动完成工作。

编辑:从技术上讲,你可以调用Set-PSReadLineKeyHandler和Register-ArgumentCompleter自己,然而,你现在有同样的问题,你需要将此添加到$profile为每个用户或机器,你想要自动完成的工作,除了在第一个地方运送你的代码。所以这并不能真正解决你的问题。

你可以创建一个脚本模块,它会动态地用你所有的cmdlet创建一个嵌套的模块清单。

下面是一个示例。psm1文件:

$files = Get-ChildItem $PSScriptRoot -Filter *.ps1
$modules = $files | Select-Object -ExpandProperty FullName
$functions = $files | Select-Object -ExpandProperty BaseName
$tmp = "$PSScriptRoottmp.psd1"
if (Test-Path $tmp) {
Remove-Item $tmp -Force
}
New-ModuleManifest -Path $tmp -NestedModules $modules -CmdletsToExport $functions
Import-Module $tmp
Remove-Item $tmp

只需修改第一行以匹配模块的文件结构。然后,您可以将.psm1作为一个模块导入。

相关内容

最新更新