Home > Mobile >  Preserve environment variables using Start-Process
Preserve environment variables using Start-Process

Time:07-17

I'll start with saying that am new to Powershell. I'm currently trying to figure out how to set an environment variable in Windows 11 using the Start-Process cmdlet. I've already tried both with admin privileges and without. This is what I'm using:

Start-Process -FilePath "pwsh" -Verb runAs -ArgumentList "-Command `"& {`"`$env:WATCHDOG_PROCID = (Start-Process C:\Users\acqui\anaconda3\envs\prog\pythonw.exe {C:\Users\acqui\Documents\Programming\Projects\Watchdog\main.py $mode} -PassThru).Id`"; pause}`""

The variable, though, is neither created, if not already present, nor modified (checking by calling Get-ChildItem Env: from the pwsh that called the subprocess). The purpose in having WATCHDOG_PROCID is to be able to kill that precise process later on.

CodePudding user response:

The process-specific environment variable you create is only visible to the pwsh process created by the outer Start-Process call, not also to the calling process.

However, in your call the pwsh process automatically terminates after defining the environment variable, so the definition is lost.

One option is to keep the pwsh session alive and continue working there, which you can do by placing the -NoExit CLI parameter before -Command.

If instead you want to define the environment variable in the calling process, make the pwsh call output the desired value (remove `$env:WATCHDOG_PROCID = from your command), capture it, and set it in the calling process.


Note: There is no way to make all processes in the user's current OS session see a newly defined environment variable:

When you define an environment variable persistently - via [System.Environment]::SetEnvironmentVariable(), as shown in this answer:

  • Running processes typically do not pick up this change.

    • Only if running processes are specifically designed to listen to environment changes, and act on them by reloading the redefined environment variable(s), do they see the change(s) right away.
  • Processes created later in the same OS session may see the changes, but that depends on how they are launched.

    • For instance, processes launched later from a preexisting PowerShell session would not see the changes, because they inherit the PowerShell session's environment, and PowerShell itself is not designed to pick up persistent environment changes dynamically.

In short:

  • Given that you're trying to define a value that by definition only has meaning in the current OS session - the ID of a launched process - using a persistent environment variable is not the right storage mechanism, and a process-scoped environment variable must be set on a per-process basis.

  • You could still use a persistent environment-variable definition, IF the other processes that need to know about the variable explicitly look up the definition in the registry.

    • Alternatively, you could designate a file to store the value in, or use a custom registry location.

    • Either way, the information will be stale when the current OS session ends, so you may need extra work to determine whether the currently persisted value is relevant to the current OS session or not (such as comparing the timestamp of when the persistent value was written to the timestamp of when the current OS session was started).

  • Related