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