Поделиться через


Визуализация привязки параметров

Привязка параметров — это процесс, используемый PowerShell для определения используемого набора параметров и связывания значений (привязки) к параметрам команды. Эти значения могут поступать из командной строки и конвейера.

Процесс привязки параметров начинается с именованных и позиционных аргументов командной строки. После привязки аргументов командной строки PowerShell пытается привязать любые входные данные конвейера. Существует два способа привязки значений из конвейера. Параметры, принимаюющие входные данные конвейера, имеют один или оба из следующих атрибутов:

  • ValueFromPipeline — значение из конвейера привязано к параметру на основе его типа. Тип аргумента должен соответствовать типу параметра.
  • ValueFromPipelineByPropertyName — значение из конвейера привязано к параметру на основе его имени. Объект в конвейере должен иметь свойство, соответствующее имени параметра или одному из его псевдонимов. Тип свойства должен совпадать или быть преобразован в тип параметра.

Дополнительные сведения о привязке параметров см. в about_Parameter_Binding.

Использование Trace-Command для визуализации привязки параметров

Устранение неполадок привязки параметров может быть сложной задачей. Командлет Trace-Command можно использовать для визуализации процесса привязки параметров.

Рассмотрим следующий сценарий. У вас есть каталог с двумя текстовыми файлами и file1.txt [file2].txt.

PS> Get-ChildItem

    Directory: D:\temp\test\binding

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/17/2024 12:59 PM              0 [file2].txt
-a---           5/17/2024 12:59 PM              0 file1.txt

Вы хотите удалить файлы, передав имена файлов через конвейер в Remove-Item командлет.

PS> 'file1.txt', '[file2].txt' | Remove-Item
PS> Get-ChildItem

    Directory: D:\temp\test\binding

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a---           5/17/2024 12:59 PM              0 [file2].txt

Обратите внимание, что Remove-Item удалено file1.txt только и не [file2].txt. Имя файла включает квадратные скобки, которые рассматриваются как дикое карта выражение. С помощью Trace-Commandможно увидеть, что имя файла привязано к параметру Remove-ItemPath .

Trace-Command -PSHost -Name ParameterBinding -Expression {
    '[file2].txt' | Remove-Item
}

Выходные данные могут Trace-Command быть подробными. Каждая строка выходных данных префиксируется с помощью метки времени и сведений о поставщике трассировки. В выходных данных этого примера сведения префикса были удалены, чтобы упростить чтение.

BIND NAMED cmd line args [Remove-Item]
BIND POSITIONAL cmd line args [Remove-Item]
BIND cmd line args to DYNAMIC parameters.
    DYNAMIC parameter object: [Microsoft.PowerShell.Commands.FileSystemProviderRemoveItemDynamicParameters]
MANDATORY PARAMETER CHECK on cmdlet [Remove-Item]
CALLING BeginProcessing
BIND PIPELINE object to parameters: [Remove-Item]
    PIPELINE object TYPE = [System.String]
    RESTORING pipeline parameter's original values
    Parameter [Path] PIPELINE INPUT ValueFromPipeline NO COERCION
    BIND arg [[file2].txt] to parameter [Path]
        Binding collection parameter Path: argument type [String], parameter type [System.String[]],
            collection type Array, element type [System.String], no coerceElementType
        Creating array with element type [System.String] and 1 elements
        Argument type String is not IList, treating this as scalar
        Adding scalar element of type String to array position 0
        BIND arg [System.String[]] to param [Path] SUCCESSFUL
    Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
    Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
    Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName WITH COERCION
    Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName WITH COERCION
MANDATORY PARAMETER CHECK on cmdlet [Remove-Item]
CALLING ProcessRecord
CALLING EndProcessing

С помощью Get-Helpможно увидеть, что параметр Remove-Item Path принимает строковые объекты из конвейера ByValue илиByPropertyName. LiteralPath принимает строковые объекты из конвейера ByPropertyName.

PS> Get-Help Remove-Item -Parameter Path, LiteralPath

-Path <System.String[]>
    Specifies a path of the items being removed. Wildcard characters are permitted.

    Required?                    true
    Position?                    0
    Default value                None
    Accept pipeline input?       True (ByPropertyName, ByValue)
    Accept wildcard characters?  true


-LiteralPath <System.String[]>
    Specifies a path to one or more locations. The value of LiteralPath is used exactly as it's
    typed. No characters are interpreted as wildcards. If the path includes escape characters,
    enclose it in single quotation marks. Single quotation marks tell PowerShell not to interpret
    any characters as escape sequences.

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

Выходные данные Trace-Command показывают, что привязка параметров начинается с параметров командной строки привязки, за которым следует входные данные конвейера. Вы увидите, что Remove-Item получает строковый объект из конвейера. Этот строковый объект привязан к параметру Path .

BIND PIPELINE object to parameters: [Remove-Item]
    PIPELINE object TYPE = [System.String]
    RESTORING pipeline parameter's original values
    Parameter [Path] PIPELINE INPUT ValueFromPipeline NO COERCION
    BIND arg [[file2].txt] to parameter [Path]
    ...
        BIND arg [System.String[]] to param [Path] SUCCESSFUL

Так как параметр Path принимает дикие карта символы, квадратные скобки представляют собой дикое карта выражение. Однако это выражение не соответствует файлам в каталоге. Чтобы указать точный путь к файлу , необходимо использовать параметр LiteralPath .

Get-Command показывает, что параметр LiteralPath принимает входные данные из конвейера ByPropertyName или ByValue. И, что он имеет два псевдонима, PSPath и LP.

PS> (Get-Command Remove-Item).Parameters.LiteralPath.Attributes |
>> Select-Object ValueFrom*, Alias* | Format-List

ValueFromPipeline               : False
ValueFromPipelineByPropertyName : True
ValueFromRemainingArguments     : False

AliasNames : {PSPath, LP}

В следующем примере Get-Item используется для извлечения объекта FileInfo . Этот объект имеет свойство с именем PSPath.

PS> Get-Item *.txt | Select-Object PSPath

PSPath
------
Microsoft.PowerShell.Core\FileSystem::D:\temp\test\binding\[file2].txt

Затем объект FileInfo передается Remove-Itemв .

Trace-Command -PSHost -Name ParameterBinding -Expression {
    Get-Item *.txt | Remove-Item
}

В выходных данных этого примера сведения префикса были удалены и разделены для отображения привязки параметров для обеих команд.

В этом выходных данных видно, что Get-Item привязывает значение *.txt позиционного параметра к параметру Path .

BIND NAMED cmd line args [Get-Item]
BIND POSITIONAL cmd line args [Get-Item]
    BIND arg [*.txt] to parameter [Path]
        Binding collection parameter Path: argument type [String], parameter type [System.String[]],
            collection type Array, element type [System.String], no coerceElementType
        Creating array with element type [System.String] and 1 elements
        Argument type String is not IList, treating this as scalar
        Adding scalar element of type String to array position 0
        BIND arg [System.String[]] to param [Path] SUCCESSFUL
BIND cmd line args to DYNAMIC parameters.
    DYNAMIC parameter object: [Microsoft.PowerShell.Commands.FileSystemProviderGetItemDynamicParameters]
MANDATORY PARAMETER CHECK on cmdlet [Get-Item]

В выходных данных трассировки для привязки параметров можно увидеть, что Remove-Item получает объект FileInfo из конвейера. Так как объект FileInfo не является объектом String, он не может быть привязан к параметру Path.

Свойство PSPath объекта FileInfo соответствует псевдониму параметра LiteralPath. PSPath также является объектом String, поэтому его можно привязать к параметру LiteralPath без приведения типов.

BIND NAMED cmd line args [Remove-Item]
BIND POSITIONAL cmd line args [Remove-Item]
BIND cmd line args to DYNAMIC parameters.
    DYNAMIC parameter object: [Microsoft.PowerShell.Commands.FileSystemProviderRemoveItemDynamicParameters]
MANDATORY PARAMETER CHECK on cmdlet [Remove-Item]
CALLING BeginProcessing
CALLING BeginProcessing
CALLING ProcessRecord
    BIND PIPELINE object to parameters: [Remove-Item]
        PIPELINE object TYPE = [System.IO.FileInfo]
        RESTORING pipeline parameter's original values
        Parameter [Path] PIPELINE INPUT ValueFromPipeline NO COERCION
        BIND arg [D:\temp\test\binding\[file2].txt] to parameter [Path]
            Binding collection parameter Path: argument type [FileInfo], parameter type [System.String[]],
                collection type Array, element type [System.String], no coerceElementType
            Creating array with element type [System.String] and 1 elements
            Argument type FileInfo is not IList, treating this as scalar
            BIND arg [D:\temp\test\binding\[file2].txt] to param [Path] SKIPPED
        Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
        Parameter [Path] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
        Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
        Parameter [LiteralPath] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
        BIND arg [Microsoft.PowerShell.Core\FileSystem::D:\temp\test\binding\[file2].txt] to parameter [LiteralPath]
            Binding collection parameter LiteralPath: argument type [String], parameter type [System.String[]],
                collection type Array, element type [System.String], no coerceElementType
            Creating array with element type [System.String] and 1 elements
            Argument type String is not IList, treating this as scalar
            Adding scalar element of type String to array position 0
            BIND arg [System.String[]] to param [LiteralPath] SUCCESSFUL
        Parameter [Credential] PIPELINE INPUT ValueFromPipelineByPropertyName WITH COERCION
    MANDATORY PARAMETER CHECK on cmdlet [Remove-Item]
    CALLING ProcessRecord
CALLING EndProcessing
CALLING EndProcessing