Reputation: 3193
In a Powershell script (.ps1) Launched from the command line of a console (cmd.exe)
How can set and environment variable in the console,
so that when the Powershell script ends processing,
and exits to the console where was invoked...
the environment variable exists,
and can be read by a batch file,
or viewed with the SET command ?
do not want to set a 'Machine' or a 'User' variable...
only a console process variable...
the same variable you get if you use SET in the console
Upvotes: 1
Views: 578
Reputation: 440679
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.
-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.
Upvotes: 3