Modify registry key/value under HKEY_USERS (HKCU Workaround)

  • 8 December 2020
  • 2 replies
  • 653 views

Userlevel 5

Hey guys,

It has come up a few times that modifying HKCU in a worklet doesn’t behave as expected. This is because the process is running under the SYSTEM account. So only the keys under the SYSTEM SID (S-1-5-18 ) will be modified if you point to HKCU:\.

This evaluates and sets the desired value for every local user account tied to that device:

Evaluation

#Define desired registry settings
$regPath = "Key Path Here"
$regName = "Property/Value Name Here"
$desiredValue = "I'm a String"

#Get User details including SID from Get-LocalUser
$users = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount = 'True'"


#Add HKEY_USERS to a PSDrive for easy access later
New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS -ErrorAction SilentlyContinue | Out-Null

$nonCompliant = @()

#Loop through the list of users to check each for compliance
foreach ($user in $users) {
    #Retrieve SIDs for each user
    $sid = $user.SID
    $name = $user.Name
    #Load Registries for users, if ntuser.dat exists
    #this prevents us from attempting to load Administrator and similar accounts
    if (Test-Path "C:\Users\$name\ntuser.dat") {
        #Load user's ntuser.dat into the registry
        & reg load "HKU\$sid" "C:\Users\$name\ntuser.dat" | Out-Null
        $properties = Get-ItemProperty -Path "HKU:\$sid\$regpath"
        $value = $($properties.$regName)
        
        #If this value doesn't match the desired value, add the user name to nonCompliant list
        if ($value -ne $desiredValue) {
            $nonCompliant += $name
        }
    }
}

#Clean-up the PSDrive
Remove-PSDrive -Name HKU

#If any users are non-compliant, "Exit 1" to flag remediation. Else "Exit 0" for Compliant
if ($nonCompliant.Count -gt 0) {
    Exit 1
} else { Exit 0}

Remediation

#Define desired registry settings
$regPath = "Key Path Here"
$regName = "Property/Value Name Here"
$desiredValue = "I'm a String"
$propertyType = 'Binary'

#Get User details including SID from Get-LocalUser
$users = Get-WmiObject -Class Win32_UserAccount -Filter "LocalAccount = 'True'"

#Add HKEY_USERS to a PSDrive for easy access later
New-PSDrive -PSProvider Registry -Name HKU -Root HKEY_USERS

foreach ($user in $users) {
    #Retrieve SIDs for each user
    $sid = $user.SID
    $name = $user.Name
    #Load Registries for users, if ntuser.dat exists
    #this prevents us from attempting to load Administrator and similar accounts
    if (Test-Path "C:\Users\$name\ntuser.dat") {
        #Load user's ntuser.dat into the registry
        & reg load "HKU\$sid" "C:\Users\$name\ntuser.dat"
        #Create Key
        New-Item -Path "HKU:\$sid\$regPath" -ItemType Directory -Force
        #Create Value
        New-ItemProperty -Path "HKU:\$sid\$regPath" -Name $regName -PropertyType $propertyType -Value $desiredValue
    }
}

Remove-PSDrive -Name HKU

2 replies

Userlevel 4

Try this.

 

Also, here’s another example that doesn’t use GMI to enumerate users.

 

I just tried to use this code to edit a registry key and I Got the following error.

ERROR: A required privilege is not held by the client.
Get-ItemProperty : Cannot find path ‘HKU:\S-1-5-21-2015044887-3745614883-1194307576-1001\HKLM:\ystem\CurrentControlSet\Control\Terminal Server’ because it does not exist.
At line:10 char:23

  •     $properties = Get-ItemProperty -Path "HKU:\$sid\$regpath"
    
  •                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    
    • CategoryInfo : ObjectNotFound: (HKU:\S-1-5-21-2…Terminal Server:String) [Get-ItemProperty], ItemNotFoundException
    • FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetItemPropertyCommand

The goal is to Disable RDP

$regPath = “HKLM:\System\CurrentControlSet\Control\Terminal Server”
$regName = “fDenyTSConnections”
$desiredValue = “1”

Reply