Monday, April 25, 2011

How to Pass a Variable to PowerShell from a DOS Batch File

Update: Many thanks to @ye110wbeard for a much simpler solution to pass the current working directory to a powershell command from a DOS batch file.


Powershell -executionpolicy remotesigned -file %~dp0\YourScript.ps1.


Scott


------------------------------------------------------


I'm sure there is a better way, but here is a way to pass the current directory for an executing batch file to a PowerShell script, to execute a PowerShell script that is in that directory. Then control returns to the batch file. Thanks to Wes' Puzzling Blog for the tip on the %~dp0 trick!





  • Echo the current directory to a text file in the $pshost directory. This is almost always the directory c:\windows\system32\WindowsPowerShell\v1.0.




  • The command to do this in the batch files is:
    echo %~dp0 > c:\windows\system32\WindowsPowerShell\v1.0\currentBatchPath.txt




  • Now start the PowerShell session, read the file contents into a variable. The variable will end in a backslash, so use substring to parse out all but the last character. Then use the Set-Location to change to the batch directory, and execute the PowerShell script.




  • The (ugly) command looks like this:




  • powershell -executionpolicy remotesigned $currentBatchPath=get-content c:\Windows\System32\WindowsPowerShell\v1.0\currentBatchPath.txt;Set-Location $currentBatchPath.substring(0,($currentBatchPath.Length-1));.\YourPowerShellScript.ps1

4 comments:

ye110wbeard said...

Actually I did just a session on that at TEC2011. You can pass variables to Powershell in the normal manner.

Run Powershell.exe -file Scriptname.PS1 -executionpolicy RemoteSigned %param1% %param2% %param3%

Just like in Dos :)

Scott said...

I appreciate your comment. In fact, my blog made use of that very thing.

I am afraid that I didn't make very clear that the reason this came up is that the PowerShell session initializes to the $pshome directory, which is not where the batch file is. In my installation packages, I never know to which directory Operations is going to save the package. The PS script in the batch cannot then run because the directory is not known in advance. I first tried doing as you suggested, but the PS session lost the command variable by the time it needed it.

ye110wbeard said...

Actually what you can ALSO do to bypass the file is pass the parameter for the Path straight through. I just made a custom Batch file that launches Powershell with Parameters and found it will accept the Modified %~dp0 as a normal parameter.... Like This

(filename LaunchPS.CMD)
Powershell.exe -executionpolicy RemoteSigned -file C:\Powershell\Script.PS1 %~dp0 %1 %2 %3 %4 %5 %6 %7 %8 %9

You can read the value for %~dp0 as $args[0] and pass that along to the receiving Powershell Script Directly :)

Scott said...

Hot-dang, if that doesn't just work beautifully. Thanks a million! I would be happy to post a link to you as a token of thanks if you wish.