I've a .bat file that starts a process, and I want to perform some automation by using a powershell script. The bat file must remain reasons that don't depend on me. The .bat file contains the definitions of some environment variable, something like:
@echo Opening solution.
set QTDIR=C:\Environment\Qt\5.15.2\msvc2019_64
set PHYSX_HEADER=C:\Environment\PhysX-3.3-3.3.4-1.3.4\PhysXSDK\Include
set PHYSX_LIB_DEBUG=C:\Environment\PhysX-3.3-3.3.4-1.3.4\PhysXSDK\Lib\vc16win64
set DDS_ROOT=C:\Environment\OpenDDS-DDS-3.16\
set ACE_ROOT=C:\Environment\OpenDDS-DDS-3.16\ACE_Wrappers\
set TAO_ROOT=C:\Environment\OpenDDS-DDS-3.16\ACE_Wrappers\TAO\
rem Setting doxygen
for /f "delims=" %%i in ('where doxygen') do set DOXYGEN_EXECUTABLE="%%i"
"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe" /Log "%USERPROFILE%\MyVSLog.xml" MySolution.sln
exit
This due to the fact that different projects needs env variables with same name but different content.
Now I want to create in the powershell script context the same enviornment variables that I create in the .bat file, so they can be used by compilers and other processes that needs them defined.
In the powershell script I'm able to read the name and the value of environemnts variables stored in the bat file, with following code (verbose due to debugging purposes):
$startBatFile = "$rootPath/Start_Solution.bat"
# Read environment variables
Select-String '^set ([^=]*)=(.*)' $startBatFile | ForEach-Object {
"object is $_"
$splitted = $_.Line.Split("=")
"splitted is $splitted"
$nameSplitted = $splitted[0].Split(" ")
$variableName = $nameSplitted[1]
$variableValue = $splitted[1]
"- Set env variable $variableName to value $variableValue"
Set-Variable -Name "env:$variableName" -Value $variableValue
}
In the loop I can set, for example, $variableName
to QTDIR
and $variableValue
to C:\Environment\Qt\5.15.2\msvc2019_64
.
But I cannot set them as environment variables. I'd like to have the same behaviour as setting them manually:
$env:MyEnvVariable = $someValue
but using env
does not seem to work with Set-Variable
. I cannot assign them directly because I'd like to avoid to have paths defined in more than one place, and because I should be able to load in the script different .bat files that contains diffferent definitions for environment variables, so they are not fixed and I cannot write them directly in the powershell code.
How can I set environment variables in powershell script by reading them from the .bat file?
CodePudding user response:
Use Set-Content
, not Set-Variable
:
# Note: Parameters -Path and -Value are implied.
Set-Content "env:$variableName" $variableValue
Set-Variable
is only intended for PowerShell's own variables, not for environment variables.
PowerShell exposes environment variables via the provider model, in the form of the Environment
provider, which exposes the Env:
drive (try Get-ChildItem Env:
).
The usual form of referring to environment variables, with verbatim names (e.g. $Env:USERNAME
) is an instance of namespace variable notation, and the equivalent of a Get-Content
call (e.g. Get-Content Env:USERNAME
) or, in the case of assigning a value, Set-Content
(as shown above); see this answer for more information.
Since you're providing the name of your environment variables indirectly - via the value of (regular) variable $variableValue
- namespace notation is not an option, and an explicit Set-Content
call is required.