Batch launching PowerShell with a multiline command parameter

13,426

Solution 1

You can add ' ^' to continue the string that you are assigning to a variable. This creates the command as a single line, so you need to use ';' between statements:

@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%

If the only code you need to execute is PowerShell, you can use something like:

;@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

which pipes all lines not starting with ";@F" to PowerShell.

Edit: I was able to start PowerShell in a separate window and allow cmd to exit with this:

@@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
}

Note that there must be 2 spaces after setting the 'LF' variable since we are assigning a line feed to the variable.

Solution 2

Use

start powershell -NoExit -EncodedCommand "aQBmACAAKAAkAHQAcgB1AGUAKQAKAHsACgBXAHIAaQB0AGUALQBIAG8AcwB0ACAAIgBSAGUAcwB1AGwAdAAgAGkAcwAgAFQAcgB1AGUAIgAKAH0ACgBlAGwAcwBlAAoAewAKAFcAcgBpAHQAZQAtAEgAbwBzAHQAIAAiAFIAZQBzAHUAbAB0ACAAaQBzACAARgBhAGwAcwBlACIACgB9AAoA"

Quoting from 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

You can use a command that would otherwise require awkward escaping via -EncodedCommand by simply supplying a Base64-encoded string.

Solution 3

You could use -Command - which causes ps to read it's commands from stdin. Put your commands in a file, and invoke

powershell -Command - <myCommandFile

Solution 4

The way of Joey is foolproof, but you could also use a simple multiline command in your case

The empty lines are necessary here (like in the LF sample of Rynant)

powershell -command if ($true)^

{^

Write-Host "Result is True"^

}^

else^

{^

Write-Host "Result is False"^

}

Here is an explanation of Long commands split over multiple lines

Share:
13,426
mcu
Author by

mcu

Updated on June 07, 2022

Comments

  • mcu
    mcu almost 2 years

    I want to pass several lines of code from a batch file to powershell.exe as -command parameter.

    For example, code like this:

    SET LONG_COMMAND=
    if ($true)
    {
    Write-Host "Result is True"
    }
    else
    {
    Write-Host "Result is False"
    }
    
    START Powershell -noexit -command "%LONG_COMMAND%"
    

    I would like to do it without creating a PowerShell script file, only a batch file.
    Is it possible?

    Thanks.