Understanding executing PowerShell inside batch with parameters
I've been digging in this for a while, but I could not understand how this works. What I need is:
- Be able to run a batch file
- The batch file should have parameters
- The parameters should be passed from the batch file to the PowerShell script that is in the same file
Why I need this? Because I need to run a simple batch file to do some stuff, but I need advanced functionality that works only from PowerShell. Specifically: I need a SaveFileDialog
for some application.
The following is what I have right now, where I stripped the complicated parts of SaveFileDialog
, and left a simple batch + PowerShell part:
<# :
@echo off
setlocal
powershell -noprofile "iex (${%~f0} | out-string)"
goto :EOF
#>
Write-Host "Hello, I'm PowerShell!"
If I put all this in a batch file, say, myfile.bat
. It runs and calls PowerShell and writes that message.
My question/request: How can I run myfile.bat param1 param2 param3
, and get these arguments/parameters be passed to my PowerShell script? I'd really appreciate a minimal example that just prints the parameters through PowerShell's write-host
.
Solution 1:
How can I run myfile.bat param1 param2 param3, and get these arguments/parameters be passed to my PowerShell script?
Build a Batch Script to Accept Arguments
You'd obviously need to scale the batch arguments up with subsequent SET arg#=%~#
I made the example batch script show arguments setting variables up top and have those passed to a PS script that will tie in with a final result later to help clarify more at the end of this answer hopefully.
Example Batch Script
@ECHO ON
SET arg1=%~1
SET arg2=%~2
SET arg3=%~3
SET arg4=%~4
SET PSScript=C:\Users\User\Desktop\Test.ps1
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%' '%arg1%' '%arg2%' '%arg3%' '%arg4%'"
EXIT /B
Build a PowerShell Script to Accept Arguments
You'd obviously need to scale the PowerShell arguments up with subsequent $arg#=$args[#]
Example PowerShell Script
$arg1=$args[0]
$arg2=$args[1]
$arg3=$args[2]
$arg4=$args[3]
Write-Host "$arg1 is a beauty!!"
Write-Host "$arg2 is cool!!"
Write-Host "$arg3 has body odor!!"
Write-Host "$arg4 is a beast!!"
Tying it Together
-
Pass arguments to the batch script:
c:\users\user\desktop\test.cmd "Selena" "Justin" "Donald" "Bernie"
Pass arguments to the PowerShell script:
Powershell -ExecutionPolicy Bypass -Command "& 'C:\Users\User\Desktop\Test.ps1' 'Selena' 'Justin' 'Donald' 'Bernie'
Full results echo on:
-
c:\users\user\desktop\test.cmd "Selena" "Justin" "Donald" "Bernie" SET arg1=Selena SET arg2=Justin SET arg3=Donald SET arg4=Bernie SET PSScript=C:\Users\User\Desktop\Test.ps1 SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0 CD /D "C:\Windows\System32\WindowsPowerShell\v1.0" Powershell -ExecutionPolicy Bypass -Command "& 'C:\Users\User\Desktop\Test.ps1' 'Selena' 'Justin' 'Donald' 'Bernie'" Selena is a beauty!! Justin is cool!! Donald has body odor!! Bernie is a beast!!
Further Resources
-
Command Line arguments (Parameters)
%* in a batch script refers to all the arguments (e.g. %1 %2 %3 %4 %5 ...%255) only arguments %1 to %9 can be referenced by number.
PowerShell Parameters / Arguments
Solution 2:
Passing Multiple Arguments to a PowerShell Script via Batch Script
You may be able to use something like the below method since I was able to get the batch script to pass arguments to the PS script using that syntax.
It does have to build a dynamic PS script up top (The :DynamicPSScriptBuild
routine) and it'll delete it if it already exists then and it will also delete it once it's done processing all executions.
I had to use the PS -file
rather than the -iex
(the reason the PS1 file needs to exist and the dynamic build of it) but it works as expected when I tested it passed the applicable arguments to the script one-by-one with each argument being one PS script execution iteration.
I wasn't sure if you needed all arguments passed to the PS script one after the other or all being passed at once or how you're PS script logic would handle multiple arguments passed to it during the same execution but perhaps this will give you enough detail to adjust accordingly.
The part of the below script that has FOR %%A IN ("Hello I'm PowerShell!", "Goodbye I'm Leaving", "Come with it and get some more"
will be the part you put each string to use as an argument to be passed to the PS script one after the other per execution iteration where each string value is in the double quotes and separated by commas.
Script Example
(You might want to turn @ECHO OFF
and take out the pause
command since I used those to help show everything per iteration to confirm all worked as expected)
<# :
@ECHO ON
SETLOCAL
:DynamicPSScriptBuild
SET PSScript=%~f0.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
ECHO param($a) >>"%PSScript%"
ECHO Write-Host "$a" >>"%PSScript%"
:SetPSScriptArguments
FOR %%A IN ( "Hello I'm PowerShell!",
"Goodbye I'm Leaving",
"Come with it and get some more"
) DO CALL :Powershell "%%~A"
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"
GOTO :EOF
:PowerShell
PowerShell -NoProfile -ExecutionPolicy Bypass -file "%PSScript%" "%~1"
pause
GOTO :EOF
Further Resources
- FOR
- CALL