Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change specific registry setting for another user in powershell

Goal:

To edit a specific registry key setting for a specific user, and no others, in powershell.

Known:

OS: Windows 8.1 Embedded Industry Pro (Same as Win 8.1, but with some embedded features)

I can do this manually on the target machine by opening REGEDIT, selecting HKU, then click on File Menu, click on Load Hive, navigate to the user's profile directory, e.g: c:\users\MrEd and when prompted, type in 'ntuser.dat' - import HKEY_CURRENT_USER. The Hive will be loaded into HKU where you can navigate and make necessary modifications.

Summary:

I have a powershell script that returns the SID of the specific user, but when used in context of the registry hive, the hive"is not found" -- so I'm guessing I must be missing a step? How does one "Load Hive" from Powershell? Or am I missing a special, magical, goats-entrails-on-keyboard incantation somewhere?

Param(
    [string]$user= $null
)


Function GetSIDfromAcctName()
{
    Param(
        [Parameter(mandatory=$true)]$userName
    )
    $myacct = Get-WmiObject Win32_UserAccount -filter "Name='$userName'" 
    return $myacct.sid
}

if($user)
{
    $sid = GetSIDfromAcctName $user
    New-PSDrive HKU Registry HKEY_USERS
    $myHiveEntry = Get-Item "HKU:\${sid}"
    Write-Host "Key:[$myHiveEntry]"
}
like image 358
Redgum Avatar asked Aug 13 '15 22:08

Redgum


People also ask

Can you use PowerShell to edit registry?

You can still use other tools you already have available to perform filesystem copies. Any registry editing tools—including reg.exe , regini.exe , regedit.exe , and COM objects that support registry editing, such as WScript. Shell and WMI's StdRegProv class can be used from within Windows PowerShell.

Do registry changes apply to all users?

The HKEY_LOCAL_MACHINE\Software\Classes key contains default settings that can apply to all users on the local computer. The HKEY_CURRENT_USER\Software\Classes key contains settings that override the default settings and apply only to the interactive user.


1 Answers

Your existing code should work for a user whose hive is already loaded (like a currently logged in user), but it makes no attempt to load the hive.

I don't know of a way to make a programmatic call to load a hive, but you can shell out to reg.exe.

This ends up being kind of janky. It seems to have issues unloading the hive if it's in use anywhere, so I've put a bunch of crap in place in this sample to try to get rid of stuff that might be holding it open, but in my tests, it can take quite a while before the reg unload command is successful, hence the whole retry portion in the finally block.

This is super unpolished, I just whipped it up on the spot.

Function GetSIDfromAcctName()
{
    Param(
        [Parameter(mandatory=$true)]$userName
    )
    $myacct = Get-WmiObject Win32_UserAccount -filter "Name='$userName'" 
    return $myacct.sid
}

$user = 'someuser'

$sid = GetSIDfromAcctName -userName $user

$path = Resolve-Path "$env:USERPROFILE\..\$user\NTUSER.DAT"

try {
    reg load "HKU\$sid" $path 

    #New-PSDrive -Name HKUser -PSProvider Registry -Root "HKEY_USERS\$sid"

    #Get-ChildItem HKUser:\

    Get-ChildItem Registry::\HKEY_USERS\$sid

} finally {

    #Remove-PSDrive -Name HKUser

    [System.GC]::Collect()
    [System.GC]::WaitForPendingFinalizers()

    $retryCount = 0
    $retryLimit = 20
    $retryTime = 1 #seconds

    reg unload "HKU\$sid" #> $null

    while ($LASTEXITCODE -ne 0 -and $retryCount -lt $retryLimit) {
        Write-Verbose "Error unloading 'HKU\$sid', waiting and trying again." -Verbose
        Start-Sleep -Seconds $retryTime
        $retryCount++
        reg unload "HKU\$sid" 
    }
}

This doesn't use a PS drive, but that code is in there too, commented out.

Note that if you don't name the hive mount point with the SID, you won't actually need the SID at all because you use the username to find the NTUSER.DAT file anyway.

like image 68
briantist Avatar answered Nov 12 '22 05:11

briantist