Durante años, he usado el cmd/DOS/Windowsshell y he pasado argumentos de línea de comandos a archivos por lotes. Por ejemplo, tengo un archivo, zuzu.baty en ella, el acceso I %1, %2, etc. Ahora, quiero hacer lo mismo cuando llamo a un PowerShellguión when I am in a Cmd.exe shell. Tengo un script xuxu.ps1(y agregué 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 $argsvariable. Siempre tiene una longitud de 0.
Si estoy en un PowerShellcaparazón, 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.
¿Es posible? y si lo es, cómo?
La muestra que no puedo hacer para trabajar es trivial, foo.ps1:
Write-Host "Num Args:" $args.Length;
foreach ($arg in $args) {
Write-Host "Arg: $arg";
}
Los resultados siempre son así:
C:\temp> foo
Num Args: 0
C:\temp> foo a b c d
Num Args: 0
c:\temp>
fuente

xuxu p1 p2 p3 p4").Después de examinar la documentación de PowerShell, descubrí información útil sobre este problema. No puede usar el
$argssi usó elparam(...)al principio de su archivo; en su lugar, necesitarás usar$PSBoundParameters. Copié / pegué su código en un script de PowerShell y funcionó como era de esperar en la versión 2 de PowerShell (no estoy seguro de en qué versión estaba cuando se encontró con este problema).Si está usando
$PSBoundParameters(y esto SOLO funciona si está usandoparam(...)al principio de su script), entonces no es una matriz, es una tabla hash, por lo que deberá hacer referencia a ella usando el par clave / valor.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:argsY cuando se llama con ...
El resultado es...
Num Args: 4 $p1=a $p2=b $p3=c $p4=dfuente
pwsh .\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4, realmente no le gusta eso. Por otro lado, si estoy en PowerShell y lo hago.\ParamTest.ps1 -arg1 val1 -listOfArgs val2 val3 val4, eso funciona como esperaba. Escuché que así es como debe funcionar debido a "razones de seguridad".Powershell>pwsh .\ParamTest.ps1 val1 val2 val3 val4rendimientos:Num Args: 4 $p1=val1 $p2=val2 $p3=val3 $p4=val4parames una construcción de lenguaje, sin embargo, debe ser lo primero en el archivo. ¿Declaraste una variable o algo más antes? Más información aquí: docs.microsoft.com/en-us/powershell/module/…Bien, primero esto está rompiendo una característica de seguridad básica en PowerShell. Con ese entendimiento, así es como puede hacerlo:
Es posible que también desee incluir un
-NoProfileargumento en función de lo que haga su perfil.fuente
Puede declarar sus parámetros en el archivo, como param:
[string]$para1 [string]$param2Y luego llame al archivo PowerShell así
.\temp.ps1 para1 para2....para10, etc.fuente
Tal vez pueda envolver la invocación de PowerShell en un
.batarchivo como este:rem ps.bat @echo off powershell.exe -command "%*"Si luego colocó este archivo en una carpeta en su
PATH, podría llamar scripts de PowerShell como este:Sin embargo, las citas pueden ser un poco complicadas:
ps write-host """hello from cmd!""" -foregroundcolor greenfuente
Es posible que no obtenga "xuxu p1 p2 p3 p4" como parece. Pero cuando está en PowerShell y establece
Puede ejecutar esos scripts como este:
o
o
Espero que eso te haga sentir un poco más cómodo con PowerShell.
fuente
si desea invocar scripts de ps1 desde cmd y pasar argumentos sin invocar el script como
powershell.exe script.ps1 -c test script -c test ( wont work )puedes hacer lo siguiente
setx PATHEXT "%PATHEXT%;.PS1;" /m assoc .ps1=Microsoft.PowerShellScript.1 ftype Microsoft.PowerShellScript.1=powershell.exe "%1" %*Esto es asumiendo que powershell.exe está en su camino
https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/ftype
fuente