如何列出 PowerShell 中定义的所有重载 cmdlet?

Ben*_*est 5 powershell

背景:我们的一个团队有一个 Chocolatey 包,调用Expand-Archive. 但是,我pscx安装的模块提供了一个Expand-Archivecmdlet,其参数签名与内置 cmdlet 不同,并导致此包安装失败。解决方案是在出现此类重载的情况下使用模块限定名称。最后能够查看在线文档来获取模块名称的价值。

最初,我尝试使用以下方法获取模块:

Get-Command Expand-Archive -All
Run Code Online (Sandbox Code Playgroud)

但这仅列出了pscx模块中找到的 cmdlet。似乎Get-Command -All 不会从尚未加载的可用模块返回命令。这对于无法自动加载的模块来说有点有意义,但对于像 之类的内置模块来说则不然Microsoft.PowerShell.Archive,这是令人担忧的,因为它使我无法在不先加载模块的情况下审核会话中的可用命令。

一旦我使用以下方法之一加载模块:

Microsoft.PowerShell.Archive\Expand-Archive
Import-Module Microsoft.PowerShell.Archive
Run Code Online (Sandbox Code Playgroud)

Get-Command Expand-Archive -All确实按解析顺序显示了两个定义以及它们所属的模块。但这是有问题的,因为它限制了我审核系统上可用命令的能力,而不是在运行之前盲目导入所有可用模块Get-Command(这本身就是一个有问题的解决方案)。


问题:我如何才能告诉实际检索会话可用的所有可解析命令,或通过其他方式获取此信息Get-Command?由于模块是根据其功能之一的第一次使用自动导入的(有人知道该命令位于卸载的模块中以进行导入),我希望应该能够支持这一点。Get-Command

mkl*_*nt0 4

要从可用模块[1]Export-Archive中查找所有命令(而不是当前加载(导入)的命令):

Get-Module -ListAvailable |
  ForEach-Object { 
    if ($cmd = $_.ExportedCommands['Expand-Archive']) { $cmd }
  }
Run Code Online (Sandbox Code Playgroud)

注意:[System.Management.Automation.PSModuleInfo]Get-Module 输出的实例还具有特定于命令类型的.ExportedAliases.ExportedFunctions.ExportedCmdlets属性,以及.ExportedVariables.

笔记:

  • 如果您安装了包含此类命令的模块的多个版本,则每个版本的命令将单独列出。

  • 输出不会告诉您哪个Export-Archive命令是有效的Export-Archive,即如果您作为命令提交,实际上会执行哪个命令;要找到有效的方法,请使用Get-Command Export-Archive.


至于你尝试过的

Get-Command原则上默认包含可用模块中的命令,但默认情况下仅显示该名称的有效命令。

-All开关旨在按给定名称显示所有可用命令,甚至是那些被有效命令隐藏的命令。

正如您所观察到的,使用-All意外地将源自模块的命令的候选池限制为来自当前加载的模块的命令,最高可达 PowerShell Core 7.2.0-preview.9。

可以说,这是一个错误,并已在GitHub 问题 #16116中报告


可选Get-Command信息:

Get-Command没有 name ( -Name) 参数的行为- 无论是否有-All- 都有点晦涩(尽管大部分都有记录):

  • 除非您传递-Type( -CommandType) 参数来显式控制要报告的命令类型,否则仅报告以下命令类型:AliasFunctionFilterCmdlet,其中特别排除ExternalScript*.ps1脚本文件)和Application(外部程序)。

    • 注意:-Type接受多个值,因此要查找所有外部脚本和程序,例如,通过-Type ExternalScript, Application
  • 要报告所有命令类型,请使用-Type All

  • 奇怪的是,不指定-Name参数似乎会应用该开关,即总是-All包含隐藏命令。

相反,如果指定-Name参数,则将考虑所有命令类型,并且是否-All指定确实产生影响。

  • 因此,Get-Command *实际上等同于Get-Command -Type All

[1] 通过 中列出的目录可发现的$env:PSModulePath,即通过模块自动加载