Devin
Devin

Reputation: 257

Registry: Search for known String Value and return the name of the SubKey it resides in

I have an automation app I am developing for an isolated environment. One of its features will be to automate clearing a Windows user profile from the registry path HKLM\Software\Microsoft\Windows NT\CurrentVersion\ProfileList\

The trouble I am having is in how to determine I am removing the correct subkey, as each subkey under this path is cryptic. I can identify the correct subkey visually in regedit by opening each subkey and inspecting for the String Value I am looking for (ProfileImagePath = C:\Users\USERANME).

Example: Subkey = S1-5-21-420551719-245851362-9522986-177556

Contains String Value = ProfileImagePath = C:\Users\n9000988

I already have a function that seeks and finds all available usernames, then a user control to select which username to work with.

So in this example, n9000988 is defined and selected.

So now I just need the ability to define what subkey the stringvalue resides in. Once I have that, I can then call to remove the subkey as that is the end goal of this sub.

What I've tried so far:

For Each subKeyName As String In My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows NT\CurrentVersion\ProfileList").GetSubKeyNames()
        For Each profPath As String In My.Computer.Registry.LocalMachine.OpenSubKey("Software\Microsoft\Windows NT\CurrentVersion\ProfileList\" & subKeyName).GetValue("ProfileImagePath")
            MsgBox(profPath)
        Next
    Next

But this returns a MsgBox for each and every character in ProfileImagePath for all subkeys that contain the string ProfileImagePath.

I almost feel like my logic in this sub is trying to go too far forward before it can determine how to get the name of the subkey.

This one is making my brain hurt. Any help would be appreciated.

UPDATE: That was perfect and so clean!!! End result -

Public Class Dialog3

Private Function Username_To_SID(ByVal Username As String) As String
    Return New Security.Principal.NTAccount(Username).Translate(GetType(Security.Principal.SecurityIdentifier)).Value
End Function


Private Sub OK_Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OK_Button.Click

    ' Kill SearchIndexer to release locked files
    Try
        Process.GetProcessesByName("SearchIndexer")(0).Kill()
    Catch ex As Exception
    End Try

    Dim userID As String = Dialog1.ListBox1.SelectedItem
    Dim userPath As String = "C:\users\" & userID

    ' Rename user folder
    Try
        My.Computer.FileSystem.RenameDirectory(userPath, userID & ".BAK")
    Catch ex As Exception
        MsgBox("Failed to rename user folders path")
    End Try

    Try
        My.Computer.Registry.LocalMachine.DeleteSubKey("Software\Microsoft\Windows NT\CurrentVersion\ProfileList\" & (Username_To_SID(Dialog1.ListBox1.SelectedItem)))

    Catch ex As Exception
        MsgBox("Failed to remove registry entry in ProfileList")

    End Try

    Me.DialogResult = System.Windows.Forms.DialogResult.OK
    Dialog1.Close()
    Me.Close()
End Sub

Upvotes: 1

Views: 1543

Answers (1)

ElektroStudios
ElektroStudios

Reputation: 20464

I want to suggest you to stop using/searching/parsing registry techniques while you are programming in .NET, you can do it all using pure .NET code.

If I understanded good what you want is to know the equivalent SID of an Username, then you could use this:

' [ Username To SID ]
'
' // By Elektro H@cker
'
' Usage Examples:
' MsgBox(Username_To_SID("Administrator")) ' Result like: S-1-5-21-250596608-219436059-1115792336-500

''' <summary>
''' Returns the SecurityIdentifier of an existing Username.
''' </summary>
''' <param name="Username">Indicates the username to retrieve the SID.</param>
Private Function Username_To_SID(ByVal Username As String) As String

    Return New Security.Principal.NTAccount(Username).
               Translate(GetType(Security.Principal.SecurityIdentifier)).Value

End Function

Upvotes: 1

Related Questions