Pass the Node.js environment variable to Windows PowerShell

I am trying to pass an environment variable to Node.js using PowerShell as follows:

C:\Users\everton\my-project> $env:MY_VAR = 8000 node index.js 

But I get an error in PowerShell:

Token 'node' unexpected expression or statement

+14
source share
3 answers

MY_VAR set the environment variable MY_VAR and run your application as follows:

 C:\Users\everton\my-project> $env:MY_VAR="8000" ; node index.js 

You can access the environment variable MY_VAR inside index.js using

 process.env.MY_VAR 

Note. PowerShell does not directly support team scope variables. The above command sets the environment variable for this PowerShell session.

+17
source

My answer requires using the Node.js and npm libraries.

... or you just get rid of scripting with an incomprehensible WTF language and use one of the Node.js scripts for the command area (plus cross-platform):

  • cross-env (for built-in)

     cross-env MYVAR=MYVALUE node index.js 
  • env-cmd (from .env file)

     env-cmd .env node index.js 

    with

     #.env file MYVAR=MYVALUE 
+6
source

Note: If you can assume that Node.js is already installed - as is by definition the case when you're invoking [TG40] - consider use of [TG41] helper packages, as shown in Cyril CHAPON helpful answer .
This answer focuses on generic solutions from within PowerShell.

TL; dr

 # Set env. variable temporarily, invoke the external utility, remove / restore old value. $oldVal, $env:MYVAR = $env:MYVAR, 8000; node index.js; $env:MYVAR = $oldVal # More structured alternative that uses a local variable. & { $oldVal, $env:MY_VAR = $env:MY_VAR, 8000; node index.js; $env:MY_VAR = $oldVal } 

Simply put, if there is no pre-existing MY_VAR value to be restored.

 $env:MYVAR=8000; node index.js; $env:MYVAR=$null # More structured alternative & { $env:MY_VAR=8000; node index.js; $env:MY_VAR=$null } 

See explanation and alternative based on helper function below.


In addition to Harikrishnan 's effective answer :

PowerShell does not have an equivalent for the media transfer method that the POSIX-like shell offers (starting with PowerShell v7 - however introducing it into PowerShell - not necessarily with the same syntax) discusses this issue of GitHub ); eg.:

  # Eg, in *Bash*: # Define environment variable MY_VAR for the child process being invoked ('node') # ONLY; in other words: MY_VAR is scoped to the command being invoked # (subsequent commands do not see it). MY_VAR=8000 node index.js 

In PowerShell, as the answer of Harikrishnan shows, you first need to define the environment variable, and then call the external program in a separate expression , so $env:MY_VAR="8000"; node index.js $env:MY_VAR="8000"; node index.js is the right PowerShell solution, but it costs nothing to keep $env:MY_VAR in scope for the remainder of the session (this is set at the process level ).

Note that even using the script block called with & to create a child region does not help here, since such child regions only apply to PowerShell variables, not environment variables.

Of course, you can remove the environment variable manually after calling node :
Remove-Item env:MY_VAR or even just $env:MY_VAR = $null , this is what the 1st command above shows.


A more structured alternative β€” perhaps better when setting multiple environment variables and / or calling multiple commands β€” is to use a script block called with & :

 & { $oldVal, $env:MY_VAR = $env:MY_VAR, 8000; node index.js; $env:MY_VAR = $oldVal } 

This takes advantage of:

  • { ... } - a script block that provides a clearly visible grouping for teams in it; called with & , creates a local scope, so the auxiliary variable $oldVal automatically leaves the scope when it exits the block.

  • $oldVal, $env:MY_VAR = $env:MY_VAR, 8000 saves the old value (if any) from $env:MY_VAR to $oldVal when changing the value to 8000 ; This method of simultaneously assigning to multiple variables (called destructuring assignment in some languages) is explained in Get-Help about_Assignment_Operators , section " Get-Help about_Assignment_Operators MULTIPLE VARIABLES".

Alternatively , use the helper function described below , or use the try { ... } finally { ... } approach, as shown in this related mine answer .


Helper function for changing the environment in the command area.

If you defined a helper function below (remember that function definitions must be placed before they are called), you can achieve a change in the environment on the command line as follows:

 # Invoke 'node index.js' with a *temporarily* set MY_VAR environment variable. Invoke-WithEnvironment @{ MY_VAR = 8000 } { node index.js } 

Invoke-WithEnvironment() source code :

 function Invoke-WithEnvironment { <# .SYNOPSIS Invokes commands with a temporarily modified environment. .DESCRIPTION Modifies environment variables temporarily based on a hashtable of values, invokes the specified script block, then restores the previous environment. .PARAMETER Environment A hashtable that defines the temporary environment-variable values. Assign $null to (temporarily) remove an environment variable that is currently set. .PARAMETER ScriptBlock The command(s) to execute with the temporarily modified environment. .EXAMPLE > Invoke-WithEnvironment @{ PORT=8080 } { node index.js } Runs node with environment variable PORT temporarily set to 8080, with its previous value, if any #> param( [Parameter(Mandatory)] [System.Collections.IDictionary] $Environment, [Parameter(Mandatory)] [scriptblock] $ScriptBlock ) # Modify the environment based on the hashtable and save the original # one for later restoration. $htOrgEnv = @{} foreach ($kv in $Environment.GetEnumerator()) { $htOrgEnv[$kv.Key] = (Get-Item -EA SilentlyContinue "env:$($kv.Key)").Value Set-Item "env:$($kv.Key)" $kv.Value } # Invoke the script block try { & $ScriptBlock } finally { # Restore the original environment. foreach ($kv in $Environment.GetEnumerator()) { # Note: setting an environment var. to $null or '' *removes* it. Set-Item "env:$($kv.Key)" $htOrgEnv[$kv.Key] } } } 
+4
source

Source: https://habr.com/ru/post/1265913/


All Articles