To run a PowerShell script from cmd.exe
invariably requires a (powershell.exe
/ pwsh.exe
) child process, and child processes fundamentally cannot set environment variables for their parent process[1].
Your best bet is to have your *.ps1
file output the name and value of the desired environment variable and then have the calling cmd.exe
process create it, based on that output.
Security note: Blindly defining environment variables based on the name-value pairs output by another command (a *.ps1
script, in your case) should only be done if you trust that command not to output malicious definitions.
Here's a simple example (run directly from an interactive cmd.exe
session):
for /f "delims== tokens=1,*" %v in ('powershell.exe -c "'FOO=bar'"') do @set "%v=%w"
The above defines environment variable %FOO%
with value bar
, based on the PowerShell command outputting the literal name-value pair FOO=bar
.
Verify with echo %FOO%
.
To extend this approach to defining multiple environment variables, make the command output each definition on its own line (which in PowerShell you can achieve by outputting an array of strings):
for /f "delims== tokens=1,*" %v in ('powershell.exe -c "'FOO=bar', 'BAZ=bam'"') do @set "%v=%w"
The above additionally defines %BAZ%
with value bam
.
To make this more convenient, I suggest creating a wrapper batch file (*.cmd
) that performs the above:
Note that you'll have to use %%v
and %%w
instead of %v
and %w
there.
Instead of -c
(for -Command
) with the demo command, use -File
with the path to your *.ps1
file to invoke it.
- Also consider use of
-NoProfile
as well, to bypass loading of your PowerShell environment's $PROFILE
file, which not only slows things down, but may pollute your command's output.
[1] As LotPings points out, child processes inherit copies of the parent process' environment variables. Modifications of these copies are never seen by the parent. A child process is fundamentally unable to modify its parent's environment, which is a restriction at the OS level - for good reasons: Modifying a running process' environment by an arbitrary (child) process would be a serious security concern.