How to use vcvars64.bat from Powershell?

Tyler Denniston's Avatar

Tyler Denniston

28 Mar, 2018 08:40 PM


I'd like to be able to use the Visual C++ toolset (cl.exe etc) for generating nmake makefiles with our CMake setup. The only support page I found ( has a solution that does not work for Powershell build scripts. Is there any way to "source" the batch file from within Powershell? Or do I have to migrate my whole build script to be cmd.exe and not PS?

  1. 1 Posted by Ilya Finkelshte... on 28 Mar, 2018 10:30 PM

    Ilya Finkelshteyn's Avatar

    Hi Tyler,

    Not sure if I understand the problem correctly. Running PowerShell scripts is fully supported in build process:


  2. 2 Posted by Tyler Denniston on 29 Mar, 2018 12:26 PM

    Tyler Denniston's Avatar

    Hi Ilya,

    Thanks for the reply. I actually am only using PowerShell for my build script blocks, which I think is part of my problem. Because my build scripts are run in PowerShell, I can't directly follow the instructions from, because call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" is a batch command, not a PowerShell command.

    I have tried & "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" and Start-Process "cmd.exe /c C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" but these do not work, as the environment variables set by vcvars64.bat are not inherited by the PowerShell session. For example, after executing either of those in PowerShell, the cl.exe, link.exe and other binaries are still not in the shell's PATH.

    Essentially I am asking: is there a PowerShell equivalent of call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat"?

  3. Support Staff 3 Posted by Feodor Fitsner on 29 Mar, 2018 03:27 PM

    Feodor Fitsner's Avatar

    Right, if you run .cmd from PowerShell its environment variables won't be imported.

    To workaround that I'd propose a little "hack".

    1. Add set > %temp%\vcvars.txt command to the end of vcvars64.bat, something like:
    Add-Content -Path "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" -Value "set > %temp%\vcvars.txt"
    1. Call vcvars64.bat from PowerShell.

    2. Import variables from vcvars.txt:

    if (Test-Path "$env:temp\vcvars.txt") {
        $lines = Get-Content "$env:temp\vcvars.txt"
        foreach($line in $lines) {
            $idx = $line.IndexOf('=')
            if($idx -ne -1) {
                [System.Environment]::SetEnvironmentVariable($line.Substring(0, $idx), $line.Substring($idx + 1))

    I haven't tested this solution - it's just an idea, but you can give it a try.

  4. 4 Posted by Tyler Denniston on 29 Mar, 2018 04:10 PM

    Tyler Denniston's Avatar

    Thanks, with your help and I got something that seems to work. I added this to my PS build script:

    if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") {
      cmd.exe /c "call `"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd`" /x64 && call `"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat`" x86_amd64 && set > %temp%\vcvars.txt"
    } else {
      cmd.exe /c "call `"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat`" && set > %temp%\vcvars.txt"
    Get-Content "$env:temp\vcvars.txt" | Foreach-Object {
      if ($_ -match "^(.*?)=(.*)$") {
        Set-Content "env:\$($matches[1])" $matches[2]
  5. Support Staff 5 Posted by Feodor Fitsner on 29 Mar, 2018 04:14 PM

    Feodor Fitsner's Avatar

    Yep, that's much nicer solution. Thanks for sharing that.

  6. Ilya Finkelshteyn closed this discussion on 25 Aug, 2018 02:27 AM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts


? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac