Freigeben über


Visualisieren einer Parameterbindung

Parameterbindung ist der Prozess, mit dem PowerShell den verwendeten Parametersatz bestimmt und den Parametern eines Befehls (Bindungs-)Werte zuordnet. Diese Werte können aus der Befehlszeile und der Pipeline stammen.

Der Parameterbindungsprozess beginnt mit der Bindung benannter und positioneller Befehlszeilenargumente. Nach dem Binden von Befehlszeilenargumenten versucht PowerShell, Pipelineeingaben zu binden. Es gibt zwei Möglichkeiten, wie Werte von der Pipeline gebunden werden. Parameter, die Pipelineeingaben akzeptieren, weisen eines oder beide der folgenden Attribute auf:

  • ValueFromPipeline: Der Wert aus der Pipeline wird basierend auf dem Typ an den Parameter gebunden. Der Typ des Arguments muss mit dem Typ des Parameters übereinstimmen.
  • ValueFromPipelineByPropertyName: Der Wert aus der Pipeline wird basierend auf dem Namen an den Parameter gebunden. Das Objekt in der Pipeline muss über eine Eigenschaft verfügen, die dem Namen des Parameters oder einem seiner Aliase entspricht. Der Typ der Eigenschaft muss mit dem Typ des Parameters übereinstimmen oder in diesen konvertiert werden können.

Weitere Informationen zur Parameterbindung finden Sie unter about_Parameter_Binding.

Visualisieren einer Parameterbindung mithilfe von Trace-Command

Die Behandlung von Parameterbindungsproblemen kann schwierig sein. Sie können das Cmdlet Trace-Command verwenden, um den Parameterbindungsprozess zu visualisieren.

Stellen Sie sich folgendes Szenario vor: Sie haben ein Verzeichnis mit zwei Textdateien, file1.txt und [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

Sie möchten die Dateien löschen, indem Sie die Dateinamen über die Pipeline an das Cmdlet Remove-Item übergeben.

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

Beachten Sie, dass Remove-Item nur file1.txt und nicht [file2].txt gelöscht hat. Der Dateiname enthält eckige Klammern, die als Platzhalterausdruck behandelt werden. Mit Trace-Command können Sie anzeigen, dass der Dateiname an den Path-Parameter von Remove-Item gebunden ist.

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

Die Ausgabe von Trace-Command kann ausführlich sein. Jeder Ausgabezeile werden ein Zeitstempel und Ablaufverfolgungsanbieterinformationen vorangestellt. Bei der Ausgabe dieses Beispiels wurden die vorangestellten Informationen entfernt, um das Lesen zu erleichtern.

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

Mithilfe von Get-Help können Sie anzeigen, dass der Path-Parameter von Remove-Item Zeichenfolgenobjekte aus der Pipeline ByValue oder ByPropertyName akzeptiert. LiteralPath akzeptiert Zeichenfolgenobjekte aus der Pipeline 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

Die Ausgabe von Trace-Command zeigt, dass die Parameterbindung mit dem Binden von Befehlszeilenparametern beginnt, gefolgt von der Pipelineeingabe. Sie können sehen, dass Remove-Item ein Zeichenfolgenobjekt von der Pipeline empfängt. Dieses Zeichenfolgenobjekt ist an den Path-Parameter gebunden.

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

Da der Path-Parameter Platzhalterzeichen akzeptiert, stellen die eckigen Klammern einen Platzhalterausdruck dar. Dieser Ausdruck stimmt jedoch nicht mit Dateien im Verzeichnis überein. Sie müssen den Parameter LiteralPath verwenden, um den genauen Pfad zur Datei anzugeben.

Get-Command zeigt, dass der LiteralPath-Parameter Eingaben aus der Pipeline ByPropertyName oder ByValue akzeptiert. Und dass er zwei Aliase hat: PSPath und LP.

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

ValueFromPipeline               : False
ValueFromPipelineByPropertyName : True
ValueFromRemainingArguments     : False

AliasNames : {PSPath, LP}

Im nächsten Beispiel wird Get-Item verwendet, um ein FileInfo-Objekt abzurufen. Dieses Objekt verfügt über eine Eigenschaft mit dem Namen PSPath.

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

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

Das FileInfo-Objekt wird anschließend an Remove-Item übergeben.

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

Bei der Ausgabe dieses Beispiels wurden die vorangestellten Informationen entfernt und getrennt, um die Parameterbindung für beide Befehle anzuzeigen.

In dieser Ausgabe können Sie sehen, dass Get-Item den Positionsparameterwert *.txt an den Path-Parameter bindet.

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]

In der Ablaufverfolgungsausgabe für die Parameterbindung können Sie sehen, dass Remove-Item ein FileInfo-Objekt aus der Pipeline empfängt. Da ein FileInfo-Objekt kein String-Objekt ist, kann es nicht an den Path-Parameter gebunden werden.

Die PSPath-Eigenschaft des FileInfo-Objekts entspricht einem Alias für den LiteralPath-Parameter. PSPath ist ebenfalls ein String-Objekt, sodass es ohne Typkoersion an den LiteralPath-Parameter gebunden werden kann.

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