Vizualizace vazby parametrů

Vazba parametru je proces, který PowerShell používá k určení, která sada parametrů se používá, a k přidružení hodnot (svázání) k parametrům příkazu. Tyto hodnoty můžou pocházet z příkazového řádku a kanálu.

Proces vazby parametru začíná vazbou s názvem a pozičními argumenty příkazového řádku. Po vytvoření vazby argumentů příkazového řádku se PowerShell pokusí svázat libovolný vstup kanálu. Existují dva způsoby, jak jsou hodnoty vázané z kanálu. Parametry, které přijímají vstup kanálu, mají jeden nebo oba následující atributy:

  • ValueFromPipeline – hodnota z kanálu je vázána na parametr na základě jeho typu. Typ argumentu musí odpovídat typu parametru.
  • ValueFromPipelineByPropertyName – hodnota z kanálu je svázaná s parametrem na základě jeho názvu. Objekt v kanálu musí mít vlastnost, která odpovídá názvu parametru nebo některému z jeho aliasů. Typ vlastnosti se musí shodovat nebo musí být konvertibilní na typ parametru.

Další informace o vazbě parametrů najdete v tématu about_Parameter_Binding.

Slouží Trace-Command k vizualizaci vazby parametrů.

Řešení potíží s vazbou parametrů může být náročné. Pomocí rutiny Trace-Command můžete vizualizovat proces vazby parametrů.

Zvažte následující scénář. Máte adresář se dvěma textovými soubory file1.txt a [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

Soubory chcete odstranit předáním názvů souborů prostřednictvím kanálu do rutiny 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

Všimněte si, že Remove-Item pouze odstraněno file1.txt , a ne [file2].txt. Název souboru obsahuje hranaté závorky, které se považují za výraz se zástupným znakem. Pomocí Trace-Command, můžete vidět, že název souboru je vázán na path parametru Remove-Item.

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

Výstup může Trace-Command být podrobný. Každý řádek výstupu má předponu časového razítka a informace o zprostředkovateli trasování. Ve výstupu tohoto příkladu byly informace o předponě odebrány, aby se daly snadněji číst.

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

Pomocí Get-Help, můžete vidět, že Path parametr Remove-Item přijímá řetězcové objekty z kanálu ByValue nebo ByPropertyName. LiteralPath přijímá objekty řetězce z kanálu 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

Výstup ukazuje, že vazba parametrů začíná vazbou parametrů příkazového Trace-Command řádku následovanými vstupem kanálu. Uvidíte, že Remove-Item z kanálu obdrží objekt řetězce. Tento objekt řetězce je vázán na parametr 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

Vzhledem k tomu, že parametr Path přijímá zástupné znaky, hranaté závorky představují výraz se zástupnými znaky. Tento výraz ale neodpovídá žádným souborům v adresáři. K určení přesné cesty k souboru musíte použít parametr LiteralPath .

Get-Command zobrazuje, že parametr LiteralPath přijímá vstup z kanálu ByPropertyName nebo ByValue. A že má dva aliasy, PSPath a LP.

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

ValueFromPipeline               : False
ValueFromPipelineByPropertyName : True
ValueFromRemainingArguments     : False

AliasNames : {PSPath, LP}

V tomto dalším příkladu Get-Item se používá k načtení FileInfo objektu. Tento objekt má vlastnost s názvem PSPath.

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

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

FileInfo objekt je předán do Remove-Item.

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

Ve výstupu tohoto příkladu byly informace o předponě odebrány a odděleny tak, aby zobrazovaly vazbu parametrů pro oba příkazy.

V tomto výstupu vidíte, že Get-Item sváže hodnotu *.txt pozičního parametru s parametrem 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]

Ve výstupu trasování pro vazbu parametru můžete vidět, že Remove-Item přijímá FileInfo objekt z kanálu. Vzhledem k tomu, že FileInfo objekt není objekt String, nelze jej svázat s parametrem Path.

Vlastnost PSPath objektu FileInfo odpovídá aliasu pro parametr LiteralPath . PSPath je také String objekt, takže může být vázán na literalPath parametr bez převodu typu.

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