Pasar varios valores a un único parámetro de secuencia de comandos de PowerShell

96

Tengo un script al que paso el nombre del servidor en $ args.

De esta manera puedo hacer cosas en este (estos) servidor (es) usando foreach:

.\script.ps1 host1 host2 host3

foreach ($i in $args)
{
    Do-Stuff $i
}

Me gustaría agregar un parámetro opcional con nombre llamado vlan. He intentado:

Param(
    [string]$vlan
)

foreach ($i in $args)
{
    Write-Host $i
}
Write-Host $vlan

Funciona si pasa un -vlanparámetro, pero si no lo hace, el script asigna automáticamente el último nombre del servidor $vlan.

Entonces, ¿cómo puede pasar uno o varios parámetros más un parámetro con nombre opcional a un script de PowerShell?

Idealmente, aquí hay ejemplos válidos:

.\script.ps1 host1
.\script.ps1 host1 host2 host3
.\script.ps1 host1 host2 -vlan office
jcarpio
fuente

Respuestas:

177

La forma más fácil es probablemente usar dos parámetros: uno para hosts (puede ser una matriz) y otro para vlan.

param([String[]] $Hosts, [String] $VLAN)

En vez de

foreach ($i in $args)

puedes usar

foreach ($hostName in $Hosts)

Si solo hay un host, el bucle foreach se repetirá solo una vez. Para pasar varios hosts al script, páselo como una matriz:

myScript.ps1 -Hosts host1,host2,host3 -VLAN 2

...o algo similar.

Bill_Stewart
fuente
7
gracias por incluir la información sobre cómo llamar al script; a menudo me faltan piezas pequeñas como esa en powershell.
Jan Bühler
23

Los parámetros toman la entrada antes que los argumentos. Lo que debe hacer en su lugar es agregar un parámetro que acepte una matriz y convertirlo en el primer parámetro de posición. ex:

param(
    [Parameter(Position = 0)]
    [string[]]$Hosts,
    [string]$VLAN
    )

foreach ($i in $Hosts)  
{ 
    Do-Stuff $i
}

Entonces llámalo como:

.\script.ps1 host1, host2, host3 -VLAN 2

Observe la coma entre los valores. Esto los recopila en una matriz.

Frode F.
fuente
19

Una forma de hacerlo sería así:

 param(
       [Parameter(Position=0)][String]$Vlan,
       [Parameter(ValueFromRemainingArguments=$true)][String[]]$Hosts
    ) ...

Esto permitiría ingresar varios hosts con espacios.

Nitz
fuente
¡Muy agradable! Excepto que a su ejemplo le falta un ']' para cerrar el segundo atributo de parámetro.
Sebastiaan M
Esta debería ser la mejor respuesta.
Дмитро Іванов
-5

Llamo a un script programado que debe conectarse a una lista de servidores de esta manera:

Powershell.exe -File "YourScriptPath" "Par1,Par2,Par3"

Luego, dentro del script:

param($list_of_servers)
...
Connect-Viserver $list_of_servers.split(",")

El operador de división devuelve una matriz de cadena

BR1COP
fuente