2009-08-18 27 views
72

Durante años, he utilizado el shell cmd/DOS/Windows y he pasado los argumentos de la línea de comandos a los archivos por lotes. Por ejemplo, tengo un archivo, zuzu.bat y en él, tengo acceso a %1, %2, etc. Ahora, quiero hacer lo mismo cuando llamo a PowerShell script when I am in a Cmd.exe shell. Tengo un script, xuxu.ps1 (y he agregado PS1 a mi variable PATHEXT y archivos PS1 asociados con PowerShell). Pero no importa lo que haga, parece que no puedo obtener nada de la variable $args. Siempre tiene longitud 0.Cómo pasar argumentos de línea de comandos a un archivo PowerShell ps1

Si estoy en un shell PowerShell, en lugar de cmd.exe, funciona (por supuesto). Pero todavía no me siento lo suficientemente cómodo para vivir en el entorno de PowerShell a tiempo completo. No quiero escribir powershell.exe -command xuxu.ps1 p1 p2 p3 p4. Quiero escribir xuxu p1 p2 p3 p4.

Esto es posible, y si es así, ¿cómo?

La muestra no puedo ir a trabajar es trivial, foo.ps1:

Write-Host "Num Args:" $args.Length; 
foreach ($arg in $args) { 
    Write-Host "Arg: $arg"; 
} 

Los resultados son siempre así:

C:\temp> foo 
Num Args: 0 
C:\temp> foo a b c d 
Num Args: 0 
c:\temp> 

Respuesta

16

OK, así que por primera vez esta se está rompiendo una característica de seguridad básica en PowerShell. Con ese entendimiento, aquí es cómo puede hacerlo:

  1. Abrir una ventana Windows Explorer
  2. Menú Herramientas ->Opciones de carpeta -> pestaña Tipos de archivo
  3. Encuentra el tipo de archivo PS1 y haga clic en el botón avanzado
  4. Haga clic en el botón Nuevo
  5. Para Acción puesta: Abierto
  6. Para la puesta Aplicación: "C: \ WINNT \ system32 \ WindowsPowerShell \ v1.0 \ powershell.exe" "-file" "% 1" % *

es posible que desee poner un -NoProfile argumento también de acuerdo con lo que hace tu perfil.

+3

Creo que la clave está en el paso 6, donde se pasa en los parámetros a PowerShell .exe. Daniel dice que ha asociado archivos PS1 con PowerShell, pero que no pasa argumentos sin las especificaciones adicionales% 1% *. También tenga en cuenta que el parámetro -File no está disponible en V1. Es nuevo para V2. –

+0

Buena captura con respecto al parámetro -file Había olvidado eso. – EBGreen

+0

Tendré que instalar V2 antes de poder probar tu sugerencia. Gracias.Cuando dices que esto está rompiendo una característica de seguridad básica, ¿a qué se refiere "esto"? ¿Llamar a un script de PowerShell desde Cmd.exe como si fuera un archivo .com/.bat/.exe? Pasar los parámetros al script? –

4

Tal vez se puede envolver la invocación PowerShell en un archivo .bat así:

rem ps.bat 
@echo off 
powershell.exe -command "%*" 

Si a continuación colocado este archivo en una carpeta en su PATH, se podría llamar scripts de PowerShell como esto:

ps foo 1 2 3 

Citando puede ser un poco desordenado, sin embargo:

ps write-host """hello from cmd!""" -foregroundcolor green 
+0

+1 para mostrar las comillas triples. eso me tuvo atrapado por un tiempo. – DeanOC

1

Puede que no obtenga "xuxu p1 p2 p3 p4" como parece.Pero cuando se encuentra en PowerShell y se establece

PS > set-executionpolicy Unrestricted -scope currentuser 

Puede ejecutar estos scripts como este:

./xuxu p1 p2 p3 p4 

o

.\xuxu p1 p2 p3 p4 

o

./xuxu.ps1 p1 p2 p3 p4 

espero que te hace un poco más cómodo con Powe rShell.

26

This article ayuda. En particular, esta sección:

-File

ejecuta el script especificado en el ámbito local ("punto de origen"), por lo que las funciones y variables que el script crea están disponibles en la sesión actual . Ingrese la ruta del archivo de script y cualquier parámetro. El archivo debe ser el último parámetro del comando, ya que todos los caracteres que se escriben después del nombre del parámetro Archivo se interpretan como la ruta del archivo de script seguida de los parámetros del script.

es decir

powershell.exe -File "C:\myfile.ps1" arg1 arg2 arg3 

medios corren el myfile.ps1 archivo y arg1 arg2 & arg3 son los parámetros para el script de PowerShell.

8

Declara tus parámetros en el archivo, como param ([string] $ para1 ....... [string] $ param2).

ahora la palabra el archivo PowerShell como temp.ps1 para1 para2....para10, etc.

11

Después de cavar a través de la documentación de PowerShell, he descubierto alguna información útil sobre este tema. No puede usar el $args si usó el param(...) al comienzo de su archivo; en su lugar, deberá usar $PSBoundParameters. Copié/pegué su código en un script de PowerShell, y funcionó como esperaba en la versión 2 de PowerShell (no estoy seguro de la versión en la que estaba cuando se encontró con este problema).

Si está usando $PSBoundParameters (y esto ÚNICAMENTE funciona si está usando param(...) al comienzo de su secuencia de comandos), entonces no es una matriz, es una tabla hash, por lo que tendrá que hacer referencia utilizando la clave/par de valores

param($p1, $p2, $p3, $p4) 
$Script:args="" 
write-host "Num Args: " $PSBoundParameters.Keys.Count 
foreach ($key in $PSBoundParameters.keys) { 
    $Script:args+= "`$$key=" + $PSBoundParameters["$key"] + " " 
} 
write-host $Script:args 

Y cuando se le llama con ...

PS> ./foo.ps1 a b c d 

El resultado es ...

Num Args: 4 
$p1=a $p2=b $p3=c $p4=d 
Cuestiones relacionadas