I am trying to use powershell to change the path environment variable in my account for my company laptop.
I have tried to use [System.Environment]::SetEnvironmentVariable('Path','mypath','User')
It will only set the path under User Variable
When I tried [System.Environment]::SetEnvironmentVariable('Path','mypath','Machine')
I got an exception saying "Requested registry access is not allowed"
However, when I do start>Edit environment variables for your account> I can click and change the System Variable without issue.
Is there a way to do the same as above from powershell?
EDIT: there are 2 options from the start panel, "Edit environment variables for your account" and "Edit the system environment variables". I do not have the Admin right, so I can only access the first option which I can edit system variables from there.
Related
I'm writing a Chocolately package that needs to install my program and then set a User level environment variable that the program needs.
As recommended in the documentation, I've installed Chocolatey from a PowerShell terminal with elevated privileges. In my chocolatelyinstall.ps1 script I can set the environment variable with this command:
Install-ChocolateyEnvironmentVariable -VariableName "my_env_var" -VariableValue "Wibble" -VariableType User
However, when I install the package: choco install my_package -s . the environment variable is set at User level for the administrator account, rather than the standard user account.
Installing the package in a regular (non-elevated) PowerShell process, simply fails with:
Access to the path 'C:\ProgramData\chocolatey\lib\my_package\tools' is denied.
Is there any way to set the Env var on the standard user account, rather than the admin account?
All assistance is welcome!
Indeed (to recap), if your elevated process uses a different (of necessity administrative) user account than the current window-station user (the user that started the current OS user session), you cannot define environment variables for the windows-station user using the usual methods that target the HKEY_CURRENT_USER hive, as it reflects the elevating user's data.
Conversely, this means that if your window-station user is an administrator and therefore allowed to run with elevation themselves, the problem will not arise.
Workaround (takes the place of your Install-ChocolateyEnvironmentVariable call):
Determine the identify of the window-station user in terms of its SID (security identify).
Use the SID to target the window-station user's specific registry hive, under HKEY_USERS.
Use a dummy user-level [Environment]::SetEnvironmentVariable() call so as to broadcast a notification of the environment change (modifying the registry directly doesn't do that), notably so that the Windows (GUI) shell refreshes its environment.
# Get the window station user and split into domain name and user name.
$domain, $user = (Get-CimInstance Win32_ComputerSystem).UserName -split '\\'
# Obtain their SID.
$sid = [System.Security.Principal.NTAccount]::new(
$domain,
$user
).Translate([System.Security.Principal.SecurityIdentifier]).Value
# Set an environment variable for them.
Set-ItemProperty "registry::HKEY_USERS\$sid\Environment" my_env_var Wibble
# Set and remove a dummy variable for the *current user*,
# so as to notify the GUI shell that the environment changed.
('unused', $null).ForEach({
[Environment]::SetEnvironmentVariable("_PowerShell_$PID", $_, 'User')
})
I have run into a couple cases where I am trying to use a command via command line, but the command is not recognized. I have narrowed it down to an issue with environment variables. In each case, the variable is present when I retrieve the variable with the underlying C# method, but not with the shorthand, $env:myVariable
For example, if I retrieve the variable like this, I will get a value.
[Environment]::GetEnvironmentVariable('ChocolateyInstall', 'Machine')
But, if I retrieve the variable like this, nothing is returned
$env:ChocolateyInstall
I then have to do something like this to to get my command to work.
$env:ChocolateyInstall = [Environment]::GetEnvironmentVariable('ChocolateyInstall', 'Machine')
I have not been able to find a good explanation as to why I have to do this. I've looked at this documentation, but nothing stands out to me. Ideally, I would like to install a CLI and then not have to deal with checking for and assigning environment variables for the command to work.
When opening a PowerShell session, all permanently stored environment variables1 will be loaded into the Environment drive (Env:) of this current session (source):
The Environment drive is a flat namespace containing the environment
variables specific to the current user's session.
The documentation you linked states:
When you change environment variables in PowerShell, the change
affects only the current session. This behavior resembles the behavior
of the Set command in the Windows Command Shell and the Setenv command
in UNIX-based environments. To change values in the Machine or User
scopes, you must use the methods of the System.Environment class.
So defining/changing an environment variable like this:
$env:ChocolateyInstall = [Environment]::GetEnvironmentVariable('ChocolateyInstall', 'Machine')
Will change it for the current session, thus being immediately effective, but will also only be valid for the current session.
The methods of [System.Environment] are more fine grained. There you can choose which environment variable scope to address. There are three scopes available:
Machine
User
Process
The Process scope is equivalent to the Environment drive and covers the environment variables available in your current session. The Machine and the User scope address the permanently stored environment variables1. You can get variables from a particular scope like this:
[Environment]::GetEnvironmentVariable('ChocolateyInstall', 'Machine')
And set them with:
[Environment]::SetEnvironmentVariable('ChocolateyInstall', 'any/path/to/somewhere', 'Machine')
If you want to have new variables from the Machine or User scope available in your current PowerShell session, you have to create a new one. But don't open a new PowerShell session from your current PowerShell session, as it will then inherit all environment variables from your current PowerShell session (source):
Environment variables, unlike other types of variables in PowerShell,
are inherited by child processes, such as local background jobs and
the sessions in which module members run. This makes environment
variables well suited to storing values that are needed in both parent
and child processes.
So, to address the problem you described, you most probably changed your permanently stored environment variables1, while already having an open PowerShell session. If so, you just need to open a new (really new, see above) session and you will be able to access your environment variables via the Environment drive. Just to be clear, opening a new session will even reload environment variables of the Machine scope. There is no reboot required.
1 That are the environment variables you see in the GUI when going to the System Control Panel, selecting Advanced System Settings and on the Advanced tab, clicking on Environment Variable. Those variables cover the User and the Machine scope.
Alternatively, you can open this GUI directly by executing:
rundll32 sysdm.cpl,EditEnvironmentVariables
I am trying to add new Environment variable in my windows 10 system , i am using below powershell command to add System variable
$env:ITH_PYTHON_PATH = 'C:\Python27\Python.exe'
i can see command is successful in adding the new values, and i can get back value when i use command $env:ITH_PYTHON_PATH.
I cannot see updated path when i manually go to the system property Environment variable
After reboot $env:ITH_PYTHON_PATH is also not seen.
Is there any better way to add environment variable permanently?
Would something like this work?
[Environment]::SetEnvironmentVariable("ITH_PYTHON_PATH", "C:\Python27\Python.exe", "Machine")
(FMPA 12.0v5)
I have a script with 1 script step: "export records".
"run script with full access privileges" is checked for the script.
When I run the script under a full access privilege set, it works (it displays an export dialog, then exports the file).
When I run the script under a privilege set where "allow exporting" is unchecked, it fails (it does not display an export dialog, and does not export any file).
This doesn't sound correct. Anyone know what I'm doing wrong?
Actually this is correct, given you have logged in with an account that is member of a privilege set that does not allow exporting (as unchecked in the allow exporting).
You have two options;
Allowing to export in that privilege set
Mark the checkbox at the bottom of your script editor that says "execute with full privileges".
I am trying to set the environment variables of a user XYZ from the powershell of admin user ABC. I am using Start-Process to launch the powershell of user XYZ but i am not able to capture the output. All this process needs to be done in Java.
Can someone help me out.
Thanks
Ajax
When you change environment variables, the change affects only the current PowerShell session (like if you were using SET command in a Windows cmd). To make the changes permanent, you have to change them with a utility like SETX. You must also have permission to change the values.
Check this TechNet article on it: https://technet.microsoft.com/en-us/library/ff730964.aspx
Basically, you're going to want to set it using the .NET method at the machine scope:
[Environment]::SetEnvironmentVariable("TestVariable","Test Value","Machine")
You'll need to restart your Powershell session to be able to access the new environment variable after creating it.