Understanding executing powershell inside batch with parameters

7

1

I've been digging in this for a while, but I could not understand how this works. What I need is:

  1. Be able to run a batch file
  2. The batch file should have parameters
  3. 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.

Please feel free to ask for any more details. Thank you!

The Quantum Physicist

Posted 2016-07-31T13:52:44.877

Reputation: 648

Answers

3

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!!
    

    enter image description here


Further Resources

Pimp Juice IT

Posted 2016-07-31T13:52:44.877

Reputation: 29 425

Thanks, man! Unfortunately I don't need this currently, but once I do, I'll consider your answer. Thanks again! – The Quantum Physicist – 2017-05-25T07:56:00.613

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

Pimp Juice IT

Posted 2016-07-31T13:52:44.877

Reputation: 29 425

Thank you for the response. While this may be the last resort, I'm hoping there's something that doesn't require writing a temp file. A temp file may not work for what I'm planning to do, or at least it'd be obnoxious. – The Quantum Physicist – 2016-07-31T20:03:55.980

Actually my current solution is that I separated the batch and the powershell files... I'm not happy about it, but I couldn't find a clean way to put them both in one file and have parameters passed between them. Thank you for trying to help :) – The Quantum Physicist – 2016-08-01T15:15:31.413

The answer wasn't helpful for me, unfortunately, but maybe it's for someone else who doesn't mind writing temp scripts :) – The Quantum Physicist – 2016-08-01T16:19:43.393

@TheQuantumPhysicist Not sure if you're still looking for a solution, but I posted an alternative answer. Hope you got the info you're looking for – root – 2016-08-02T19:43:09.523

@root sorry man. Your solution passes scripts, not parameters. My script is huge and that makes your solution impractical. Sorry, and thanks for trying. – The Quantum Physicist – 2016-08-02T19:48:52.453

@TheQuantumPhysicist Not sure what you mean by it "passes scripts", it definitely is passing parameters. Regardless, hope you've reached your solution – root – 2016-08-02T20:04:37.240

0

Pass the batch variable directly to your Powershell line from within the batch file. To test this, I passed the Write-Host cmdlet as the argument.

foo.bat:

@echo off

set arg1=%1

powershell.exe %1 "this is from powershell"

pause

Launching the .bat with an argument,

.\foo.bat Write-Host

Output:

this is from powershell
Press any key to continue . . .

root

Posted 2016-07-31T13:52:44.877

Reputation: 2 992