Reputation: 85
Background (OS: Windows 10):
I have Powershell script that runs(in background) as SYSTEM
Through Powershell script I need to set both Machine and Logged-in User Environment Variables
Machine Variables are set using [Environment]::SetEnvironmentVariable('NAME', 'Value', 'Machine')
and works as-expected
User Variables set using [Environment]::SetEnvironmentVariable('NAME1', 'Value1', 'User')
does not work for End user accounts as the process runs as SYSTEM
Powershell script execution needs at least one user logged in and this is working fine
I am able to find the logged in user with:
$current_user = (Get-WmiObject -Class Win32_ComputerSystem).UserName.Split('\')[1]
I tried using Registry update to set logged-in User Variables but this does not work as expected:
Set-ItemProperty -Path 'HKCU:\Environment' -Name 'NAME2' -Value 'Value2' -Force
How can I set Logged-In User Env Variable from powershell script running as SYSTEM?
Upvotes: 4
Views: 4317
Reputation: 2346
In addition to the accepted answer, if you are wondering how to get the SID for one of the local system accounts like SYSTEM
refer to the table below or follow this link for complete list of Well Known SIDs:
SID | Name | Description |
---|---|---|
S-1-5-18 | Local System | A service account (SYSTEM) that is used by the operating system. |
S-1-5-19 | NT Authority | Local Service |
S-1-5-20 | NT Authority | Network Service |
To create a user variable for the local
SYSTEM
user the command would be as follows:
# set environment variable 'NAME2' for the local SYSTEM user
Set-ItemProperty -Path "Registry::HKEY_USERS\S-1-5-18\Environment" -Name 'NAME2' -Value 'Value2' -Type String
Upvotes: 0
Reputation: 23663
For troubleshooting scripts running under the SYSTEM account, I am recommend using PSExec, see: this answer.
If you user's registry hive is not yet loaded, you need to load (and Unload it when you're done), see: Powershell REG LOAD command not working.
To find the user's hive (the path is identified by the user's SID) and set the environment variable:
$UserHive = Get-ChildItem -Path 'Registry::\HKEY_USERS' |
Where-Object {(Test-Path "Registry::$_\Volatile Environment") -and (Get-ItemProperty "Registry::$_\Volatile Environment").USERNAME -eq $Username}
Set-ItemProperty -Path "Registry::$UserHive\Environment" -Name 'NAME2' -Value 'Value3' -Force
Upvotes: 3
Reputation: 61068
In order to set a registry value for the currently logged on user (which is not the one that runs the code), you need to find the users SID.
Try this:
# get the domain and username for the currently logged on user
$domain, $userName = (Get-WmiObject -Class Win32_ComputerSystem).UserName -split '\\', 2
# next, get the SID for that current user
$user = [System.Security.Principal.NTAccount]::new($domain, $userName)
$sid = $user.Translate([System.Security.Principal.SecurityIdentifier]).Value
# set the registry value for this user.
Set-ItemProperty -Path "Registry::HKEY_USERS\$sid\Environment" -Name 'NAME2' -Value 'Value2' -Type String
# See: https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.registryvaluekind?redirectedfrom=MSDN
# for other RegistryValueKind values for parameter Type
Upvotes: 4