In powershell after changing to cmd unable to call

2019-07-26 11:07发布

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 ?

3条回答
你好瞎i
2楼-- · 2019-07-26 11:55

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.

查看更多
3楼-- · 2019-07-26 12:08

try Something like this into your PowerShell script:

& start "C:\Temp\test.bat"
查看更多
叼着烟拽天下
4楼-- · 2019-07-26 12:08

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

查看更多
登录 后发表回答