如何将对象通过管道传递给特定参数

How to pipe objects to a specific parameter

我想列出一个目录中的所有 PowerShell 函数。以下命令有效:

Get-ChildItem -Path ($env:USERPROFILE + "\somewhere\*.psm1") -Recurse | ForEach-Object {Get-Command -Module $_.BaseName}

现在,我尝试将 Get-ChildItem 的输出直接传送到 cmdlet Get-Command。像这样的东西,这是行不通的:

Get-ChildItem -Path ($env:USERPROFILE + "\somewhere\*.psm1") -Recurse | Get-Command -Module {$_.BaseName}

显然,我不太明白如何以正确的方式将对象从 Get-ChildItem 传递到 Get-Command 中的参数 -Module

我有两个问题:

参数可以通过四种不同的方式绑定:

  • 按参数列表中的位置,例如,Get-ChildItem C:\(仅某些参数)
  • 通过参数列表中的名称,例如Get-ChildItem -Path C:\
  • 通过管道中的值,例如1..5 | Get-Random(仅某些参数)
  • 通过管道中的名称,例如'C:\Windows' | Get-ChildItem(仅限某些参数)

您可以通过Get-Help <command> -Parameter *查看参数绑定的各种方式。然后您可以看到 Get-Command 允许 Module 参数仅由 属性 name:

绑定
-Module [<String[]>]
    Specifies an array of modules. ...

    Required?                    false
    Position?                    named
    Default value                none
    Accept pipeline input?       True (ByPropertyName)
    Accept wildcard characters?  false

因此输入必须是具有 Module 属性 的对象才能允许绑定。因此,在您的情况下,您需要在两者之间增加一个步骤:

Get-ChildItem -Path ($env:USERPROFILE + "\somewhere\*.psm1") -Recurse |
  Select-Object @{l='Module';e={$_.Basename}} |
  Get-Command

现在,这里的这个实例有点烦人,因为 Module 参数由 属性 名称绑定,但大多数东西不会给你一个带有 [=19 的对象=] 属性。哎呀,即使 Get-Module 也没有,因为返回的对象使用 Name 作为 属性 名称,所以你甚至不能做

Get-Module | Get-Command

然而,在许多其他地方(特别是关于路径)自动工作得很好。如果你可以控制你的输入对象,例如从 CSV 或其他数据源读取时,您可以得到相当简洁的代码。

编辑: Ansgar Wiechers 指出,虽然这个 应该 有效,但实际上并没有。这可能是 PowerShell 的参数绑定算法的不足(如上所示,它非常复杂,我们也从未让它在 Pash 中正常工作),或者 Get-Command cmdlet 的参数描述方式很简单由于某些原因不能绑定。