如何将对象传递给特定参数

时间:2016-11-29 11:03:04

标签: powershell powershell-v4.0

我想从一个目录列出我的所有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以正确的方式传递到-Module中的参数Get-Command

我有两个问题:

  • 您是否有提示如何正确管道?
  • 是否可以管道输入特定参数,例如-Module,或者对象是否总是移交给一个默认参数?

1 个答案:

答案 0 :(得分:3)

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

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

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

-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参数是由属性名绑定的,但是大多数事情都没有给你一个具有Module属性的对象。哎呀,即使Get-Module也没有,因为返回的对象使用Name作为属性名称,所以你甚至不能这样做

Get-Module | Get-Command

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

编辑:Ansgar Wiechers指出,虽然工作,但实际上并非如此。这可能是PowerShell参数绑定算法的缺陷(如上所述,它非常复杂,我们也从未在Pash中正常工作),或者Get-Command cmdlet可能只是简单地描述参数因为原因不能允许绑定。