1

I created a bat file to setup my workspace by changing the directory to the workspace directory and calling the setupEnv.bat file. But while I'm executing the below bat file in PowerShell, the instructions after cmd are not executing. I need to call the setupEnv.bat file in cmd. If I remove the cmd it will work fine. But I want call the setupEnv.bat on cmd not in PowerShell.

D:
cd D:\WorkSpace\
cmd
call setupEnv.bat
echo "Setup Completed"
  • After calling the setupEnv.bat and calling cmd, will it keep all the environment variable setup in the PowerShell ?
Moerwald
  • 10,448
  • 9
  • 43
  • 83
vrnithinkumar
  • 1,273
  • 1
  • 11
  • 29

3 Answers3

3

This article addresses your exact scenario:

Windows IT Pro - Take Charge of Environment Variables in PowerShell

The reason the variables disappear is that a .bat or .cmd runs in a separate cmd.exe process (when the process terminates, you lose the variables).

The article presents a PowerShell function you can use to run a .bat or .cmd script and retain the environment variables it sets:

# Invokes a Cmd.exe shell script and updates the environment.
function Invoke-CmdScript {
  param(
    [String] $scriptName
  )
  $cmdLine = """$scriptName"" $args & set"
  & $Env:SystemRoot\system32\cmd.exe /c $cmdLine |
    Select-String '^([^=]*)=(.*)$' |
    ForEach-Object {
      $varName = $_.Matches[0].Groups[1].Value
      $varValue = $_.Matches[0].Groups[2].Value
      Set-Item Env:$varName $varValue
  }
}

The article also has a couple of functions for setting and restoring environment variable values in PowerShell.

Bill_Stewart
  • 22,916
  • 4
  • 51
  • 62
  • Yes, I _know_ a method of taking and processing output from a child `cmd` process. Thank you for a link to complete solution! However, I'd change `$cmdLine = """$scriptName"" $args & set & echo CD=%CD%"` and add consequent commands to _adopt_ child's current directory as well. – JosefZ Mar 10 '17 at 23:48
  • Rather than `$Env:SystemRoot\system32\cmd.exe`, how about `$Env:ComSpec`? – lit Sep 22 '18 at 16:19
  • Yes, unless `ComSpec` hasn't been changed to a different program that doesn't support the `cmd.exe` `set` command syntax (PowerShell, for example). – Bill_Stewart Sep 22 '18 at 17:09
0

try Something like this into your PowerShell script:

& start "C:\Temp\test.bat"
Esperento57
  • 16,521
  • 3
  • 39
  • 45
0

After calling the setupEnv.bat and calling cmd, will it keep all the environment variable setup in the PowerShell?

No. Any legacy commands invoked from PowerShell will run in a separate (child) process.

Proof:

wmic process where "name='powershell.exe' or name='cmd.exe'" get CommandLine, name, ParentProcessId, ProcessId /Value

Add above line to your batch-file, e.g. to setupEnv.bat and call it from powershell

  • either directly, e.g. D:\bat\setupEnv.bat,
  • or using & call operator & D:\bat\setupEnv.bat,
  • or . dot sourced & D:\bat\setupEnv.bat,
  • or modify all above methods calling cmd as
    • cmd /D /C D:\bat\setupEnv.bat, or
    • & cmd /D /C D:\bat\setupEnv.bat, or
    • . cmd /D /C D:\bat\setupEnv.bat.

Result is always the same or at least very alike:

PS D:\PShell> D:\bat\setupEnv.bat
"Setup Completed"

CommandLine="C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
Name=powershell.exe
ParentProcessId=4280
ProcessId=6396

CommandLine=C:\Windows\system32\cmd.exe /c ""D:\bat\setupEnv.bat""
Name=cmd.exe
ParentProcessId=6396
ProcessId=4116

Paraphrased from this Foredecker's answer to similar question:

While a child process can inherit the current environment variables, working directory etc. from parent one, there is no supported way for a child process to reach back to the parent process and change the parent's environment.

Solution: call Powershell from cmd/batch script rather than vice versa

Community
  • 1
  • 1
JosefZ
  • 28,460
  • 5
  • 44
  • 83