Si tengo una función que acepta más de un parámetro de cadena, el primer parámetro parece obtener todos los datos asignados y los parámetros restantes se pasan como vacíos.
Una secuencia de comandos de prueba rápida:
Function Test([string]$arg1, [string]$arg2)
{
Write-Host "`$arg1 value: $arg1"
Write-Host "`$arg2 value: $arg2"
}
Test("ABC", "DEF")
La salida generada es
$arg1 value: ABC DEF
$arg2 value:
La salida correcta debería ser:
$arg1 value: ABC
$arg2 value: DEF
Esto parece ser consistente entre v1 y v2 en varias máquinas, por lo que, obviamente, estoy haciendo algo mal. ¿Alguien puede señalar exactamente qué?
powershell
Nasir
fuente
fuente
Test "ABC" "DEF"
Respuestas:
Los parámetros en las llamadas a funciones en PowerShell (todas las versiones) están separados por espacios, no separados 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
está activo. Los argumentos entre paréntesis se usan solo en métodos .NET.fuente
(1,2,3)
a una función se trata efectivamente como una matriz; Un solo argumento. Si desea usar argumentos de estilo de método OO, use módulos:$m = new-module -ascustomobject { function Add($x,$y) { $x + $y } }; $m.Add(1,1)
Powershell
es un lenguaje shell y es común que los lenguajes shell utilicen espacios como separador de tokens. Yo no diría quePowershell
es ser diferente aquí, está justo en línea con otros proyectiles predeterminados del sistema comocmd
,sh
,bash
, etc.Ya se ha proporcionado la respuesta correcta, pero este problema parece lo suficientemente frecuente como para garantizar algunos detalles adicionales para aquellos que desean comprender las sutilezas.
Hubiera agregado esto solo como un comentario, pero quería incluir una ilustración; lo eliminé 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)
:Por lo tanto, se puede llamar a una función con parámetros posicionales separados por espacios o parámetros con nombre independientes del orden . Las otras trampas revelan que debe ser consciente de las comas, paréntesis y espacios en blanco.
Para leer más, vea mi artículo Down the Rabbit Hole: A Study in PowerShell Pipelines, Functions, and Parameters . El artículo contiene un enlace a la referencia rápida / gráfico de pared también.
fuente
Aquí hay algunas buenas respuestas, pero quería señalar un par de otras cosas. 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 de esta manera:
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:
El primer ejemplo funciona aunque
Name
se proporciona el segundo, porque explícitamente usamos el nombre del parámetro. Sin embargo, el segundo ejemplo funciona según la posición, porName
lo que debería 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:
Ahora la función tomará un nombre o una identificación, pero no ambos. Puede usarlos posicionalmente o por nombre. Como son de un tipo diferente, PowerShell lo resolverá. Entonces, todo esto funcionaría:
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:
Luego, en una nota al margen relacionada, también hay validación de parámetros en PowerShell. Esta es una de mis características favoritas de PowerShell, y hace que el código dentro de sus funciones sea muy limpio. Existen numerosas validaciones que puede usar. Un par de ejemplos son:
En el primer ejemplo, ValidatePattern acepta una expresión regular que garantiza que el parámetro proporcionado coincida con lo que espera. Si no es así, se produce una excepción intuitiva que le dice exactamente qué está mal. Entonces, en ese ejemplo, 'Something' funcionaría bien, pero 'Summer' no pasaría la validación.
ValidateRange garantiza que el valor del parámetro se encuentre entre el rango que espera para un 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 el más útil es ValidateScript. Esto toma un bloque de script que debe evaluar a $ true, por lo que el cielo es el límite. Por ejemplo:
En este ejemplo, estamos seguros de que no solo existe $ Path, sino que es un archivo (a diferencia 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 bloques de secuencia de comandos múltiples como hice aquí. Es extremadamente útil y ofrece buenas funciones de limpieza y excepciones intuitivas.
fuente
My_Function -NamedParamater "ParamValue"
estilo de llamada de función. Este es un patrón que más código de script PS debe seguir para facilitar la lectura.Llama a las funciones de PowerShell sin paréntesis y sin usar la coma como separador. Intenta usar:
En PowerShell, la coma (,) es un operador de matriz, p. Ej.
Se establece
$a
en una matriz con tres valores.fuente
fuente
Si eres un desarrollador de C # / Java / C ++ / Ruby / Python / Pick-A-Language-From-This-Century y quieres llamar a tu función con comas, porque eso es lo que siempre has hecho, entonces necesitas algo Me gusta esto:
Ahora llama:
y verás
fuente
Si no sabe (o no le importa) cuántos argumentos pasará a la función, también podría usar un enfoque muy simple como;
Código :
Eso imprimiría todos los argumentos. Por ejemplo:
Salida
Encuentro esto particularmente útil al crear funciones que usan comandos externos que podrían tener muchos parámetros diferentes (y opcionales), pero se basa en dicho comando para proporcionar comentarios sobre errores de sintaxis, etc.
Aquí hay otro ejemplo del mundo real (creando una función para el comando tracert, que odio tener que recordar el nombre truncado);
Código :
fuente
Si intentas:
usted obtiene:
Entonces ves que los paréntesis separan los parámetros
Si intentas:
usted obtiene:
Ahora podría encontrar alguna utilidad inmediata de los paréntesis (un espacio no se convertirá en un separador para el siguiente parámetro), sino que tendrá una función eval.
fuente
@
) antes de que los paren principales, como esta matriz vacía:@()
; o esta matriz con dos números:@(1, 2)
.Debido a que esta es una pregunta frecuente, quiero mencionar que una función de PowerShell debe usar verbos aprobados ( Verbo-sustantivo como nombre de la función). La parte verbal del nombre identifica la acción que realiza el cmdlet. La parte sustantiva del nombre identifica la entidad en la que se realiza la acción. Esta regla simplifica el uso de sus cmdlets para usuarios avanzados de PowerShell.
Además, puede especificar cosas como si el parámetro es obligatorio y la posición del parámetro:
Para pasar el parámetro a la función, puede usar la posición :
O puede especificar el nombre del parámetro :
No usa paréntesis como cuando llama a una función dentro de C #.
Recomendaría pasar siempre los nombres de los parámetros cuando se usa más de un parámetro, ya que es más legible .
fuente
Get-Node
cmdlet. Para nosotros estaría claro que tenemos que invocarGet-Node
, noRetrieve-Node
, niReceive-Node
, ni .....No sé qué está haciendo con la función, pero eche un vistazo al uso de la palabra clave 'param'. Es bastante más potente para pasar parámetros a una función, y lo hace más fácil de usar. A continuación hay un enlace a un artículo demasiado complejo de Microsoft al respecto. No es tan complicado como el artículo lo hace sonar.
Uso de parámetros
Además, aquí hay un ejemplo de una pregunta en este sitio:
Echale un vistazo.
fuente
fuente
Dije lo siguiente antes:
El problema común es usar la forma singular
$arg
, que es incorrecta. Siempre debe ser plural como$args
.El problema no es eso. De hecho,
$arg
puede ser cualquier otra cosa. El problema era el uso de la coma y los paréntesis.Ejecuto el siguiente código que funcionó y la salida sigue:
Código:
Prueba "ABC" "DEF"
Salida:
fuente
Esta es una
params
declaración adecuada .Ver about_Functions_Advanced_Parameters .
Y de hecho funciona.
fuente
También puede pasar parámetros en una función como esta:
fuente
No lo veo mencionado aquí, pero salpicar sus argumentos es una alternativa útil y se vuelve especialmente útil si está creando dinámicamente los argumentos de un comando (en lugar de usar
Invoke-Expression
). Puede salpicar con matrices para argumentos posicionales y tablas hash para argumentos con nombre. Aquí hay unos ejemplos:Splat con matrices (argumentos posicionales)
Prueba de conexión con argumentos posicionales
Con salpicaduras de matriz
Splat With Hashtable (Argumentos nombrados)
Conexión de prueba con argumentos con nombre
Con salpicaduras de Hashtable
Splat posicional y argumentos nombrados simultáneamente
Conexión de prueba con argumentos posicionales y con nombre
Splatting Array y Hashtables juntos
fuente