In PowerShell, you can easily create environment variables using a few different methods. However, these are only scoped to the current PowerShell process, and not to any process running inside the user’s profile, or any process running on the system.

Here are a few examples of methods that you can use to set environment variables in PowerShell.

### Use the variable syntax to create a new environment variable $env:FirstName = 'Trevor' ### Use the built-in env: PSDrive New-Item -Path env:\LastName -Value Sullivan ### Set an environment variable using the System.Environment .NET class [System.Environment]::SetEnvironmentVariable('DOCKER_HOST', 'docker.artofshell.com')

Each of the examples above will set an environment variable for the scope of the current process. Once that process dies, the environment variables disappear, and must be set again. So the question becomes: how do I persist environment variables in the user profile or for the entire system?

In fact, the answer isn’t too far off from the last example above! We still will leverage the SetEnvironmentVariable static method on the System.Environment class. However, there’s a method overload that takes a third input parameter of type [System.EnvironmentVariableTarget], which is a .NET enumeration. We can discover the supported values on this enumeration, by simply piping it into Get-Member -Static.

PS C:\Users\TrevorSullivan> [System.EnvironmentVariableTarget] | Get-Member -Static TypeName: System.EnvironmentVariableTarget Name MemberType Definition ---- ---------- ---------- Equals Method static bool Equals(System.Object objA, System.Object objB) Format Method static string Format(type enumType, System.Object value, string format) GetName Method static string GetName(type enumType, System.Object value) GetNames Method static string[] GetNames(type enumType) GetUnderlyingType Method static type GetUnderlyingType(type enumType) GetValues Method static array GetValues(type enumType) IsDefined Method static bool IsDefined(type enumType, System.Object value) Parse Method static System.Object Parse(type enumType, string value), static System.Object Parse(typ... ReferenceEquals Method static bool ReferenceEquals(System.Object objA, System.Object objB) ToObject Method static System.Object ToObject(type enumType, System.Object value), static System.Object... TryParse Method static bool TryParse[TEnum](string value, [ref] TEnum result), static bool TryParse[TEn... Machine Property static System.EnvironmentVariableTarget Machine {get;} Process Property static System.EnvironmentVariableTarget Process {get;} User Property static System.EnvironmentVariableTarget User {get;}

As you can see in the above output, the [System.EnvironmentVariableTarget] enumeration supports three values:

Machine

Process

User

Now let’s take a look at the method overload for the [System.Environment]::SetEnvironmentVariable() method.

PS C:\Users\TrevorSullivan> [System.Environment]::SetEnvironmentVariable OverloadDefinitions ------------------- static void SetEnvironmentVariable(string variable, string value) static void SetEnvironmentVariable(string variable, string value, System.EnvironmentVariableTarget target)

As you can see, we have two method overloads to choose from. In the very first example, we used the first method overload, which only takes two input parameters: the environment variable name, and the value we want to set it to. The other method overload allows us to specify a target for the environment variable! Let’s take a quick look at how to utilize it.

PS C:\Users\TrevorSullivan> [System.Environment]::SetEnvironmentVariable('DOCKER_HOST', 'tcp://docker.artofshell.com:2376 ', [System.EnvironmentVariableTarget]::User)

Well, that’s a bit of a long command line, but it achieves what we are interested in: setting an environment variable persistently for our user profile. The next time we log into the system, with the same user account, that environment variable will still be set. We can verify this by using the System Properties GUI for exploring environment variables:

Press WINDOWS + X , then Y

, then In the System window, click the Change settings link

window, click the link In the System Properties window, choose the Advanced tab

window, choose the tab Click the Environment Variables button

Great, that worked! So what if we tried to set a system-wide environment variable? To do that, all we need to do is change the “target” of the environment variable to Machine. If you’re not running PowerShell “as Administrator,” you might receive an error message though.

PS C:\Users\TrevorSullivan> [System.Environment]::SetEnvironmentVariable('DOCKER_HOST', 'tcp://docker.artofshell.com:2376', [System.EnvironmentVariableTarget]::Machine) Exception calling "SetEnvironmentVariable" with "3" argument(s): "Requested registry access is not allowed." At line:1 char:1 + [System.Environment]::SetEnvironmentVariable('DOCKER_HOST', 'tcp://do ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : SecurityException

If you do end up getting the error message shown above, just open an elevated PowerShell prompt, and the command should run successfully.