Compartir a través de


Visualización del enlace de parámetros

El enlace de parámetros es el proceso que PowerShell usa para determinar qué conjunto de parámetros se usa y para asociar (enlazar) valores a los parámetros de un comando. Estos valores pueden provenir de la línea de comandos y de la canalización.

El proceso de enlace de parámetros comienza enlazando los argumentos de la línea de comandos con nombre y posición. Después de enlazar argumentos de línea de comandos, PowerShell intenta enlazar cualquier entrada de canalización. Hay dos maneras de enlazar valores desde la canalización. Los parámetros que aceptan la entrada de canalización tienen uno o ambos de los atributos siguientes:

  • ValueFromPipeline: el valor de la canalización está enlazado al parámetro en función de su tipo. El tipo del argumento debe coincidir con el tipo del parámetro.
  • ValueFromPipelineByPropertyName: el valor de la canalización se enlaza al parámetro en función de su nombre. El objeto de la canalización debe tener una propiedad que coincida con el nombre del parámetro o uno de sus alias. El tipo de la propiedad debe coincidir o convertirse en el tipo del parámetro.

Para más información sobre el enlace de parámetros, consulte about_Parameter_Binding.

Usar Trace-Command para visualizar el enlace de parámetros

La solución de problemas de enlace de parámetros puede ser difícil. Puede usar el cmdlet Trace-Command para visualizar el proceso de enlace de parámetros.

Considere el siguiente escenario: Tiene un directorio con dos archivos de texto, file1.txt y [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

Para eliminar los archivos, pase los nombres de archivo, a través de la canalización, al cmdlet 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

Observe que Remove-Item solo eliminó file1.txt y no [file2].txt. El nombre de archivo incluye corchetes, que se tratan como una expresión comodín. Usando Trace-Command, puede ver que el nombre de archivo se está enlazando con el parámetro Path de Remove-Item.

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

La salida de Trace-Command puede ser detallada. Cada línea de salida tiene como prefijo una marca de tiempo e información del proveedor de seguimiento. Para la salida de este ejemplo, se ha quitado la información del prefijo para facilitar la lectura.

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

Usando Get-Help, puede ver que el parámetro Path de Remove-Item acepta objetos de cadena de la canalización ByValue o ByPropertyName. LiteralPath acepta objetos de cadena de la canalización 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

La salida de Trace-Command muestra que el enlace de parámetros se inicia mediante el enlace de parámetros de línea de comandos seguido de la entrada de canalización. Puede ver que Remove-Item recibe un objeto de cadena de la canalización. Ese objeto de cadena está enlazado al parámetro 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

Dado que el parámetro Path acepta caracteres comodín, los corchetes representan una expresión comodín. Sin embargo, esa expresión no coincide con ningún archivo del directorio. Debe usar el parámetro LiteralPath para especificar la ruta de acceso exacta al archivo.

Get-Command muestra que el parámetro LiteralPath acepta entradas de la canalización ByPropertyName o ByValue. Y que tiene dos alias, PSPath y LP.

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

ValueFromPipeline               : False
ValueFromPipelineByPropertyName : True
ValueFromRemainingArguments     : False

AliasNames : {PSPath, LP}

En este ejemplo siguiente, Get-Item se usa para recuperar un objeto FileInfo. Ese objeto tiene una propiedad denominada PSPath.

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

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

El objeto FileInfo se pasa después a Remove-Item.

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

Para la salida de este ejemplo, la información de prefijo se ha quitado y separado para mostrar el enlace de parámetros para ambos comandos.

En esta salida, puede ver que Get-Item enlaza el valor del parámetro posicional *.txt con el parámetro 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]

En la salida de seguimiento para el enlace de parámetros, puede ver que Remove-Item recibe un objeto FileInfo de la canalización. Dado que un objeto FileInfo no es un objeto String, no puede enlazarse al parámetro Path.

La propiedad PSPath del objeto FileInfo coincide con un alias del parámetro LiteralPath. PSPath es también un objeto String, por lo que puede enlazarse al parámetro LiteralPath sin conversión de tipo.

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