Running VS 2017 Build Tools in Windows PowerShell

Viewed 3476

I dislike IDEs, so I installed the VS 2017 Build Tools so I can work via command-line.

The install went fine, and everything works out of Windows CMD, however, PowerShell is much better, and I prefer to use PS. The issue here is that according to MSDN:

The Visual C++ command-line tools use the PATH, TMP, INCLUDE, LIB, and LIBPATH environment variables, and may also use tool-specific environment variables. Because the values of these environment variables are specific to your installation, and can be changed by product updates or upgrades, we recommend that you use vcvarsall.bat or a Developer Command Prompt shortcut instead of setting them yourself. For information about the specific environment variables used by the compiler and linker, see CL Environment Variables and LINK Environment Variables.

I shouldn't set the Environment Variables myself, and that's fine with me, the only issue is that when I run the vcvarsall.bat in PS, no environment variables change. I am new to PS, so I'm guessing that .bat files can't alter session environment variables. If that's the case, then I can't work out of PS. As a side note, the CL and LINK variables never show up, I'll explain below.

I figured I should find out what the variables are. I echoed all my variables to a text file before and after running the batch file, and wrote a short Java program to find anything new, or modified. These are them. As you can see the CL and LINK variables are not present.

How do I solve this issue? I was thinking of writing my own batch file, but if the first one didn't work, why would mine? I didn't see anything on the attached MSDN page, or any links there about how to make this work for PowerShell.

2 Answers
<#
.SYNOPSIS
    Invokes the specified batch file and retains any environment variable changes it makes.
.DESCRIPTION
    Invoke the specified batch file (and parameters), but also propagate any
    environment variable changes back to the PowerShell environment that
    called it.
.PARAMETER Path
    Path to a .bat or .cmd file.
.PARAMETER Parameters
    Parameters to pass to the batch file.
.EXAMPLE
    C:\PS> Invoke-BatchFile "$env:ProgramFiles\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
    Invokes the vcvarsall.bat file.  All environment variable changes it makes will be
    propagated to the current PowerShell session.
.NOTES
    Author: Lee Holmes
#>
function Invoke-BatchFile
{
    param([string]$Path, [string]$Parameters)

    $tempFile = [IO.Path]::GetTempFileName()

    ## Store the output of cmd.exe.  We also ask cmd.exe to output
    ## the environment table after the batch file completes
    cmd.exe /c " `"$Path`" $Parameters && set " > $tempFile

    ## Go through the environment variables in the temp file.
    ## For each of them, set the variable in our local environment.
    Get-Content $tempFile | Foreach-Object {
        if ($_ -match "^(.*?)=(.*)$") {
            Set-Content "env:\$($matches[1])" $matches[2]
        }
        else {
            $_
        }
    }

    Remove-Item $tempFile
}

$VcVars = 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Auxiliary\Build\vcvarsall.bat'
Invoke-BatchFile $VcVars x64
cl hello_world.cpp
Related