6

A bit of a random problem here. I set an environment variable using PowerShell like this:

$env:GOOGLE_ELEVATION_API="the_api-key"

Then in python I attempt to read it with this simple script:

from os import environ

key = environ.get("GOOGLE_ELEVATION_API")

This returns None. If I query my environment variables in PowerShell it is there. If I query it through python with os.environ it is not.

None of the results I found make reference that this should be an issue, neither on the PowerShell side nor on python's side. I have not restarted my machine since I honestly do not believe this is what should be done. I did restart my IDE in the hope that it is somehow caching the environment but thankfully it does not.

Any pointers would be great!

4
  • 1
    $env: <- only affects current runspace. Will you be running the scripts in the same user context, or do you need a machine-wide env var? Commented Mar 3, 2021 at 15:17
  • Ah. Yes. When I run this command from my PowerShell terminal in my IDE, it works. But from a separate PSD window it does not. What is the correct way to make a variable available machine wide? (I guess I can look that up quickly as well.) Commented Mar 3, 2021 at 15:27
  • @MathiasR.Jessen: environment variables exist at the process level (try $env:FOO = 'bar'; Start-ThreadJob { $env:FOO } | Receive-Job -Wait -AutoRemoveJob - perhaps that's what you meant, but note that a single process can host multiple PowerShell runspaces). A regularly invoked Python script would automatically inherit the calling PowerShell session's environment variables. Commented Mar 3, 2021 at 15:27
  • 1
    @mklement0 Ack, but I suspect it doesn't work exactly because python is not launched by powershell :-) Commented Mar 3, 2021 at 15:30

1 Answer 1

5
  • Setting an environment variable via PowerShell's $env: namespace defines it for the current process only.

    • Any Python scripts invoked directly from a PowerShell session would see such variables, however, because child processes inherit the caller's environment variables.
  • To persistently define a Windows environment variable at the machine level that all processes see, you must use .NET APIs directly (as of PowerShell 7.4):

# Note: Requires ELEVATION, due to setting at the *machine* level.
[Environment]::SetEnvironmentVariable('GOOGLE_ELEVATION_API', 'the_api-key', 'Machine')

Note that only future PowerShell sessions will see this variable,[1] and this need to restart an application in order for it to see the new variable typically also applies to other running applications.

(The exception are those applications that actively listen for the WM_SETTINGCHANGE message and refresh their environment in response, which is what the Windows GUI shell (explorer.exe) does.)

For more information about persistently setting environment variables on Windows, see this answer.


[1] However, you could define it for the current session too, by repeating the definition at the process level:
$env:GOOGLE_ELEVATION_API = 'the_api-key'

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.