次の方法で共有


パラメーター バインディングを視覚化する

パラメーター バインドは、PowerShell がどのパラメーター セットが使用されているかを判断し、値をコマンドのパラメーターに関連付ける (バインドする) ために使用するプロセスです。 これらの値は、コマンド ラインとパイプラインから取得できます。

パラメーター バインド プロセスは、名前付きおよび位置指定のコマンド ライン引数をバインドすると開始されます。 コマンド ライン引数をバインドすると、PowerShell でパイプライン入力のバインドが試みられます。 パイプラインから値をバインドする方法は 2 つあります。 パイプライン入力を受け入れるパラメーターには、次の属性のいずれかまたは両方があります。

  • ValueFromPipeline - パイプラインからの値は、その型に基づいてパラメーターにバインドされます。 引数の型は、パラメーターの型と一致する必要があります。
  • ValueFromPipelineByPropertyName - パイプラインの値は、その名前に基づいてパラメーターにバインドされます。 パイプライン内のオブジェクトには、パラメーターの名前またはそのエイリアスのうち 1 つに一致するプロパティが必要です。 プロパティの型は、パラメーターの型に一致するか、変換できる必要があります。

パラメーター バインドの詳細については、「about_Parameter_Binding」を参照してください。

Trace-Command を使用してパラメーター バインドを視覚化する

パラメーター バインドの問題のトラブルシューティングは困難な場合があります。 Trace-Command コマンドレットを使用して、パラメーター バインド プロセスを視覚化できます。

次のシナリオについて考えてみます。 file1.txt[file2].txt の2つのテキスト ファイルを含むディレクトリがあります。

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-ItemPath パラメーターがパイプライン 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 からの入力を受け入れることを示しています。 また、PSPathLP という 2 つのエイリアスがあります。

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

ValueFromPipeline               : False
ValueFromPipelineByPropertyName : True
ValueFromRemainingArguments     : False

AliasNames : {PSPath, LP}

この次の例では、Get-ItemFileInfo オブジェクトを取得するために を使用します。 そのオブジェクトには 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 によって位置指定パラメーター値 *.txtPath パラメーターにバインドされていることがわかります。

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パラメーターにバインドすることはできません。

FileInfo オブジェクトの PSPath プロパティは、LiteralPath パラメーターのエイリアスと一致します。 PSPathString オブジェクトでもあるため、強制型変換なしで 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