2012-02-20 12 views
7

Quiero pasar varias líneas de código de un archivo por lotes a powershell.exe como parámetro de comando.PowerShell de inicio por lotes con un parámetro de comando multilínea

Por ejemplo, el código de la siguiente manera:

SET LONG_COMMAND= 
if ($true) 
{ 
Write-Host "Result is True" 
} 
else 
{ 
Write-Host "Result is False" 
} 

START Powershell -noexit -command "%LONG_COMMAND%" 

quisiera hacerlo sin crear un archivo de script de PowerShell, solamente un archivo por lotes.
¿Es posible?

Gracias.

Respuesta

9

Usted puede agregar '^' para continuar la cadena que va a asignar a una variable. Esto crea el comando como una sola línea, por lo que debe usar ';' entre los enunciados:

@ECHO off 
SET LONG_COMMAND=^
if ($true)^
{^
Write-Host "Result is True";^
Write-Host "Multiple statements must be separated by a semicolon."^
}^
else^
{^
Write-Host "Result is False"^
} 

START Powershell -noexit -command %LONG_COMMAND% 

Si el único código que necesita para ejecutar es PowerShell, puede usar algo como:

;@Findstr -bv ;@F "%~f0" | powershell -command - & goto:eof 

if ($true){ 
    Write-Host "Result is True" -fore green 
} 
else{ 
    Write-Host "Result is False" -fore red 
} 

Start-Sleep 5 

cual tuberías todas las líneas que no empiezan con "; @F" a PowerShell.

Editar: pude iniciar PowerShell en una ventana separada y permitir cmd para salir con esto:

@@ECHO off 
@@setlocal EnableDelayedExpansion 
@@set LF=^ 


@@SET command=# 
@@FOR /F "tokens=*" %%i in ('Findstr -bv @@ "%~f0"') DO SET command=!command!!LF!%%i 
@@START powershell -noexit -command !command! & goto:eof 

if ($true){ 
    Write-Host "Result is True" -fore green 
} 
else{ 
    Write-Host "Result is False" -fore red 
} 

Fíjese que no debe ser de 2 espacios después de ajustar la variable 'LF' ya que estamos asignando un avance de línea a la variable.

+0

Creo que su segundo ejemplo es exactamente lo que estaba buscando. ¿Cuál es el significado de; @ en un archivo por lotes? Gracias. – mcu

+1

El '@' le dice a cmd que no haga eco de la línea mientras se ejecuta. El ';' es solo un delimitador de parámetro; ',' o '=' también se pueden usar. Solo reduce la posibilidad de que algo más en el archivo coincida con la cadena que se está filtrando. La línea puede comenzar con '@' y cualquier combinación de ';', '=' o ','. Ejemplos: ';; @', '@,', '== @ ,;', etc. – Rynant

+0

Esto funciona muy bien. Solo hay una desventaja MENOR. Al iniciar PowerShell de esta manera, tengo dos procesos en ejecución: powershell.exe y cmd.exe. Además, no hay ningún mensaje de Powershell en la ventana. ¿Es posible "iniciar" el powershell.exe y salir de cmd.exe? – mcu

5

Uso

start powershell -NoExit -EncodedCommand "aQBmACAAKAAkAHQAcgB1AGUAKQAKAHsACgBXAHIAaQB0AGUALQBIAG8AcwB0ACAAIgBSAGUAcwB1AGwAdAAgAGkAcwAgAFQAcgB1AGUAIgAKAH0ACgBlAGwAcwBlAAoAewAKAFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAiAFIAZQBzAHUAbAB0ACAAaQBzACAARgBhAGwAcwBlACIACgB9AAoA" 

Citando powershell /?

# To use the -EncodedCommand parameter: 
$command = 'dir "c:\program files" ' 
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command) 
$encodedCommand = [Convert]::ToBase64String($bytes) 
powershell.exe -encodedCommand $encodedCommand 

Se puede utilizar un comando que de otro modo requeriría incómoda escapar a través de -EncodedCommand por el simple suministro de una cadena codificada en Base64.

+0

Creo que me equivoqué. Quería decir: "Me gustaría hacerlo sin crear un archivo de script de PowerShell, solo un archivo por lotes". Entonces, ¿cómo codifico todo este código de PowerShell en un archivo por lotes? – mcu

+0

Creo que leyó mal. Vea la primera línea del código de arriba. El resto del código se cita de la ayuda y muestra cómo * crear * una cadena de comandos codificada. – Joey

+0

Bien, pero ¿cómo puedo encontrar esa cadena codificada en un archivo por lotes? Gracias. – mcu

1

Puede usar -Command - que hace que ps lea los comandos de stdin. Ponga sus comandos en un archivo, e invocan

powershell -Command - <myCommandFile 
+0

Esto probablemente funcione, pero aún requiere un archivo adicional. Me gustaría que el archivo por lotes fuera autónomo. Gracias. – mcu

+0

En ese caso, simplemente puede usar '-File', que es más fácil. – Joey

+0

@Joey Creo que ejecutar un script (como con -File) es diferente a ejecutar comandos desde la perspectiva de seguridad, pero puedo estar equivocado, no soy experto en PS. – wmz

1

La forma de Joey es infalible, pero también se puede utilizar un simple comando de varias líneas en su caso

Las líneas vacías son necesarios aquí (como en la muestra LF de Rynant)

powershell -command if ($true)^ 

{^ 

Write-Host "Result is True"^ 

}^ 

else^ 

{^ 

Write-Host "Result is False"^ 

} 

Aquí es una explicación de Long commands split over multiple lines

Cuestiones relacionadas