- Create a certificate-signed RDP shortcut via Group Policy - Fri, Aug 9 2019
- Monitor web server uptime with a PowerShell script - Tue, Aug 6 2019
- How to build a PowerShell inventory script for Windows Servers - Fri, Aug 2 2019
In this article, I'll go over a few different ways a scripter can work with environment variables in PowerShell.
Environment variables are exposed with a PowerShell drive known as "$env:". It's possible to browse through all of the environment variables by typing $env: at the console and hitting the tab key. This will allow you to see the names of each environment variable in alphabetical order.
PowerShell $Env drive
The $env: drive is the recommended place to refer to any environment variables with PowerShell. However, it's possible also to read the variables via .NET in PowerShell by using the GetEnvironmentVariable static method on the Environment class. This is essentially the same task.
[Environment]::GetEnvironmentVariable('COMPUTERNAME')
This will output the same CLIENT1 as seen above.
As you can see, reading environment variables is easy. How do we set them? There are a few ways to do this. Each method is a little different and, more importantly, makes the environment variable active during various times.
The first way to set an environment variable is to change the $env: drive's variable directly.
$env:COMPUTERNAME = 'foo'
This method works but has limitations. The main one being that the variable is only active in the current user session; it is not permanent. This means that as soon as the console is closed, this new assignment will be removed and will revert to what it originally was. This method can be used to change existing environment variables or create new ones. It also allows you to immediately refer to the environment variable (as you can see above).
What if you need to create permanent environment variables? We'll need to go into .NET to do this. To create permanent environment variables that last through a single session, we'll need to use the SetEnvironmentVariable method. This method has three arguments: the variable name, value, and type (System or User).
[Environment]::SetEnvironmentVariable("Test", "Test value.", "User")
At first, you may think that nothing happened. As you can see above, I supposedly set the variable in the user session, but $env:test does not find it. This is a downside of this method. This variable does not show up until the session has been restarted.
Just because it didn't show up in the $env drive doesn't mean it wasn't there. You could always use the GetEnvironmentVariable() method to find it without having to start a new session.
[Environment]::GetEnvironmentVariable("Test", "User")
The same approach can be applied to creating and changing system environment variables as well. However, instead of specifying "User" as the argument for Get and SetEnvironmentVariable, you would use "System" instead.
Subscribe to 4sysops newsletter!
[Environment]::SetEnvironmentVariable("Test", "Test value.", "System") [Environment]::GetEnvironmentVariable("Test", "System")
You'll find that even though using the PowerShell drive to refer to environment variables is handy, it's not real-time nor is it permanent. In my experience, I've always chosen to use the .NET methods to control environment variables. Using these methods, you're able to set environment variables permanently and retrieve them without session restarts. There have also been times when system environment variables simply don't show up in the $env drive, and you'll be forced to use the .NET methods anyway.
You can also enumerate them with Get-ChildItem -Path Env:
Good post!
Thanks Adam!
In testing this out, I found that [Environment]::GetEnvironmentVariable(“Comspec”, “System”) yielded the following error:
Cannot convert argument “target”, with value: “System”, for “GetEnvironmentVariable” to type
“System.EnvironmentVariableTarget”
[Environment]::GetEnvironmentVariable(“Comspec”, “Machine“) gives the correct result.
[Environment]::GetEnvironmentVariable(“Comspec”,”Machine”)
C:\Windows\system32\cmd.exe
How about retrieving environment values from a previously running process? How can I get them?