Saltar al contenido

¿Cómo paso varios parámetros a una función en PowerShell?

Solución:

Parámetros en llamadas a funciones en PowerShell (todas las versiones) están separados por espacios, no por comas. Además, los paréntesis son completamente innecesarios y causarán un error de análisis en PowerShell 2.0 (o posterior) si Set-StrictMode -Version 2 o superior está activo. Los argumentos entre paréntesis se utilizan solo en métodos .NET.

function foo($a, $b, $c) {
   "a: $a; b: $b; c: $c"
}

ps> foo 1 2 3
a: 1; b: 2; c: 3

Ya se ha proporcionado la respuesta correcta, pero este problema parece lo suficientemente frecuente como para justificar algunos detalles adicionales para aquellos que quieran comprender las sutilezas.

Hubiera agregado esto solo como un comentario, pero quería incluir una ilustración; lo arranqué de mi tabla de referencia rápida sobre las funciones de PowerShell. Esto supone que la firma de la función f es f($a, $b, $c):

Errores de sintaxis de una llamada a función

Por lo tanto, se puede llamar a una función con espacios separados posicional parámetros o independiente del orden llamado parámetros. Las otras trampas revelan que es necesario tener en cuenta las comas, los paréntesis, y espacio en blanco.

Para leer más, vea mi artículo. Down the Rabbit Hole: un estudio sobre canalizaciones, funciones y parámetros de PowerShell. El artículo también contiene un enlace a la referencia rápida / gráfico mural.

Aquí hay algunas buenas respuestas, pero quería señalar un par de cosas más. Los parámetros de función son en realidad un lugar donde brilla PowerShell. Por ejemplo, puede tener parámetros con nombre o posicionales en funciones avanzadas como esta:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=1)]
         [int] $Id
    )
}

Luego, podría llamarlo especificando el nombre del parámetro, o simplemente podría usar parámetros posicionales, ya que los definió explícitamente. Entonces cualquiera de estos funcionaría:

Get-Something -Id 34 -Name "Blah"
Get-Something "Blah" 34

El primer ejemplo funciona aunque Name se proporciona en segundo lugar, porque usamos explícitamente el nombre del parámetro. Sin embargo, el segundo ejemplo funciona según la posición, por lo que Name tendría que ser el primero. Cuando es posible, siempre trato de definir posiciones para que ambas opciones estén disponibles.

PowerShell también tiene la capacidad de definir conjuntos de parámetros. Utiliza esto en lugar de la sobrecarga de métodos y, de nuevo, es bastante útil:

function Get-Something
{
    [CmdletBinding(DefaultParameterSetName="Name")]
    Param
    (
         [Parameter(Mandatory=$true, Position=0, ParameterSetName="Name")]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=0, ParameterSetName="Id")]
         [int] $Id
    )
}

Ahora la función tomará un nombre o una identificación, pero no ambos. Puede usarlos posicionalmente o por su nombre. Dado que son de un tipo diferente, PowerShell lo resolverá. Entonces todos estos funcionarían:

Get-Something "some name"
Get-Something 23
Get-Something -Name "some name"
Get-Something -Id 23

También puede asignar parámetros adicionales a los distintos conjuntos de parámetros. (Ese fue un ejemplo bastante básico, obviamente). Dentro de la función, puede determinar qué conjunto de parámetros se usó con la propiedad $ PsCmdlet.ParameterSetName. Por ejemplo:

if($PsCmdlet.ParameterSetName -eq "Name")
{
    Write-Host "Doing something with name here"
}

Luego, en una nota al margen relacionada, también hay validación de parámetros en PowerShell. Esta es una de mis funciones favoritas de PowerShell y hace que el código dentro de sus funciones sea muy limpio. Existen numerosas validaciones que puede utilizar. Un par de ejemplos son:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [ValidatePattern('^Some.*')]
         [string] $Name,
         [Parameter(Mandatory=$true, Position=1)]
         [ValidateRange(10,100)]
         [int] $Id
    )
}

En el primer ejemplo, ValidatePattern acepta una expresión regular que asegura que el parámetro proporcionado coincide con lo que espera. Si no es así, se lanza una excepción intuitiva que le indica exactamente qué es lo que está mal. Entonces, en ese ejemplo, ‘Algo’ funcionaría bien, pero ‘Verano’ no pasaría la validación.

ValidateRange asegura que el valor del parámetro esté entre el rango esperado para un número entero. Entonces, 10 o 99 funcionarían, pero 101 arrojaría una excepción.

Otro útil es ValidateSet, que le permite definir explícitamente una matriz de valores aceptables. Si se ingresa algo más, se lanzará una excepción. También hay otros, pero probablemente lo más útil uno es ValidateScript. Esto toma un bloque de script que debe evaluarse como $ true, por lo que el cielo es el límite. Por ejemplo:

function Get-Something
{
    Param
    (
         [Parameter(Mandatory=$true, Position=0)]
         [ValidateScript({ Test-Path $_ -PathType 'Leaf' })]
         [ValidateScript({ (Get-Item $_ | select -Expand Extension) -eq ".csv" })]
         [string] $Path
    )
}

En este ejemplo, se nos asegura no solo que existe $ Path, sino que es un archivo (en lugar de un directorio) y tiene una extensión .csv. ($ _ se refiere al parámetro, cuando está dentro de su bloque de secuencia de comandos). También puede pasar bloques de secuencia de comandos de varias líneas mucho más grandes si se requiere ese nivel, o usar varios bloques de secuencia de comandos como hice aquí. Es extremadamente útil y ofrece buenas funciones limpias y excepciones intuitivas.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *