为什么 PowerShell 的 `Get-ChildItem` 命令将参数 `d` 解析为 `Depth`?

Nic*_*Cox 7 powershell

鉴于它Get-ChildItem具有三个以字符开头的参数D......

? (gcm Get-ChildItem).Parameters.Values |? Name -like 'd*' | select name, aliases

Name      Aliases
----      -------
Depth     {}
Debug     {db}
Directory {ad, d}
Run Code Online (Sandbox Code Playgroud)

...并且该Directory参数具有显式别名add,为什么Get-ChildItem -d解析为Get-ChildItem -Depth

? Get-ChildItem -d
Get-ChildItem: Missing an argument for parameter 'Depth'. Specify a parameter of type 'System.UInt32' and try again.
Run Code Online (Sandbox Code Playgroud)

Jay*_*kul 5

这是因为其他参数是根据您询问的路径在调用时添加的动态参数。

  • -DirectoryPath在 FileSystem 提供程序中时才有效
  • -DnsName并且-DocumentEncryptionCert仅在证书提供者中有效

-re存在相同,而-Recurse不是对-ReadOnly......

这也是与同-e-Exclude代替-Eku-ExpiriringInDays...

而且您会注意到,如果您运行Get-ChildItem -f并告诉您f不明确,那么它建议的唯一选项是-Filterand -Force, not-File-FollowSymlinkFileSystem 提供程序独有的选项......


您可以通过以下方式查看Get-Parameter可以从 PowerShell 库中获取的所有内容Install-Script Get-Parameter


我最终找到了一种通过实验证明非动态参数总是首先被解析的方法,并且参数绑定器甚至从不查看动态参数,它可以在没有它们的情况下绑定任何东西。因此,参数选择器甚至不知道动态参数的名称或别名是什么,除非在非动态参数上找不到匹配项。所以这个d别名只会引起混乱,除非它是以这样的方式生成的,它也会出现在其他命令中......

尝试这个:

using namespace System.Management.Automation
function Test-Alias {
    [CmdletBinding()]
    param(
        [switch]$Awful
    )

    dynamicparam {
        $paramDictionary = [RuntimeDefinedParameterDictionary]::new()
        $attribs = [System.Collections.ObjectModel.Collection[System.Attribute]]::new()
        $attribs.Add([ParameterAttribute]@{ParameterSetName = "_AllParameterSets" })

        $paramdictionary.Add("Automation", [RuntimeDefinedParameter]::new( "Automation", [switch], $attribs))

        $attribs += [AliasAttribute]::new("A", "C")
        $paramdictionary.Add("Architecture", [RuntimeDefinedParameter]::new( "Architecture", [switch], $attribs))
        $paramdictionary
    }
    end {
        $PSBoundParameters
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你在你的控制台中运行它,你不仅可以看到它的Test-Alias -A用途,Awful而且它Test-Alias -C确实有效!A 别名从来没有机会,但这不是因为动态参数的别名被完全忽略,而是因为有一个以该字母开头的参数不是 dynamic

现在试试这个:

Trace-Command -Name ParameterBinding { Test-Alias -A } -PSHost
Run Code Online (Sandbox Code Playgroud)

我的输出截图,懒人

并将其与您使用Test-Alias -C或时的输出进行比较Test-Alias -A -C...

您可以看到 Dynamic 参数仅在可以绑定的所有非动态参数之后才考虑。