AlwaysQuestioning
AlwaysQuestioning

Reputation: 1484

In PowerShell, how can I extract a file from HKEY_Users from all SIDs?

I am writing a PowerShell module to look for data that each user who has logged onto the computer at some point might have in their directory in HKEY_USERS. My initial thought was to mount HKEY_USERS, find a way to store each user's SID in a string variable, and then loop through all folders like so:

dir HKU\<STRING VARIABLE HOLDING SID>\Software\MyApp\Mydesireddata

Is there a way I can avoid having to loop through SIDs (because I won't know them ahead of time), and extract that file info from each SID on the system while remembering which SID it came from?

EDIT: Here is an example of the key I'm trying to extract from each user's SID using regedit (vncviewer's EulaAccepted)

enter image description here

Upvotes: 1

Views: 11115

Answers (2)

Semicolon
Semicolon

Reputation: 136

I tackled this issue a slightly different way; preferring to make use of a conspicuously placed wildcard.

Get-ItemProperty -Path Registry::HKEY_USERS\*\SOFTWARE\TestVNC\viewer\ -Name EulaAccepted | 
   Select-Object -Property @{n="SID";e={$_.PSPath.Split('::')[-1].Split('\')[1]}},EulaAccepted

The wildcard will automatically check all available paths and return what you need as well as the SID from the parent path.

As for the username (which is probably more useful than a SID), you didn't specifically ask for it, but I added it in for grins; this should cover local and domain accounts.

mind the line breaks

Get-ItemProperty -Path Registry::HKEY_USERS\*\SOFTWARE\TestVNC\viewer\ -Name EulaAccepted | 
   Select-Object -Property @{n="SID";e={$_.PSPath.Split('::')[-1].Split('\')[1]}},EulaAccepted | 
   Select-Object -Property @{n="User";e={[System.Security.Principal.SecurityIdentifier]::new($_.SID).`
     Translate([System.Security.Principal.NTAccount]).Value}},SID,EulaAccepted

Getting the username is just ugly; there's likely a cleaner way to get it, but that's what I have in my head. The double-select really makes my skin crawl - there's something unpleasant about it. I could just do a one shot thing, but then it gets so unwieldly you don't even know what you're doing by looking at it. I've included a screenshot of the registry below, and a screenshot of the screen output from running the few lines.

redacted view of the registry for one user

redacted screen output of running the above; mind the line breaks

Upvotes: 1

Mathias R. Jessen
Mathias R. Jessen

Reputation: 174485

Use Get-ChildItem to retrieve each user-specific subkey:

$UserHives = Get-ChildItem Registry::HKEY_USERS\ |Where-Object {$_.Name -match '^HKEY_USERS\\S-1-5-21-[\d\-]+$'}

Then loop over each entry and retrieve the desired registry value:

foreach($Hive in $UserHives)
{
    # Construct path from base key
    $Path = Join-Path $Hive.PSPath "SOFTWARE\MyApp\DataKey"

    # Attempt to retrieve Item property
    $Item = Get-ItemProperty -Path $Path -Name ValueName -ErrorAction SilentlyContinue

    # Check if item property was there or not    
    if($Item)
    {
        $Item.ValueName
    }
    else 
    {
        # doesn't exist
    }
}

Upvotes: 3

Related Questions