locked
Need help with Registry manipulation RRS feed

  • Question

  • I want to do search and replace under a certain registry key. My code is blow:

    $path = "\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components"
    echo "Enumerating $path"
    cd hklm:$path
    $keys = ls
    echo "Found $($keys.count) components"
    
    $find = "\mount\1"
    $keys | % {
        $key = $_
        $names = $key.getvaluenames()
        $names | % {
            $name = $_
            $value = $key.GetValue($name)
            if ($value.Contains($find)) {
                echo "$($key.name) $name $value"
                $value = $value.replace($find, "")
                #$key.SetValue($name, $value)
                break
            }
            break
        }
    }
    
    echo "End of processing"

    I am not familiar with PS syntax; I have difficulties with the code and cannot get it working. I'd prefer using PS specific syntax for getting/setting value names.

    Any suggestions are appreciated.



    • Edited by Neo the 1 Friday, September 14, 2018 8:16 PM
    Friday, September 14, 2018 8:14 PM

Answers

  • Try this. Always test thoroughly first!!!! 

    function Analyze($keys)
    {  
     foreach ($k in $keys)
     {
       "Found key $k"
       
        # Now we can query the values in the key.
        $vals = Get-Item -path "Registry::$k"
        if ($vals.Count -gt 0)                                          # If we have subkeys
        {
            CheckValues $vals                    
        }
        
        # Let's recurse through all subkeys.
        $rwg = Get-ChildItem  -path "Registry::$k"  -ErrorAction SilentlyContinue    
        if ($rwg.Count -gt 0)                                          # If we have subkeys
        {
            Analyze $rwg                    
        }
     }
    }
    function CheckValues($vals)
    {   
     foreach ($v in $vals.getvaluenames())
     {
       "Found value: $v "
       $valdata =  $vals.GetValue($v)
       "Found value data: $valdata "
       if(($valdata.tostring()) -imatch $findme)       # Powershell is case sensitive, imatch is not
       {
           "We have a match!!!"
           $valdata = $valdata -replace $findme,$replaceme    #-replace is not case sensitive
           "New value data: $valdata "
           $rc = New-ItemProperty -Path "Registry::$vals"  -Name $v -Value $valdata ` -force   # remove -force or add -whatif to test
       }
     }  
    }
    # Powershell requires functions to be defined before inline code.
    $findme = "foO2"               
    $replaceme = "Success"
    $path = "HKEY_CURRENT_USER\Software\Test"
    "Enumerating $path"
    $rwg = Get-ChildItem  -path "Registry::$path"
    Analyze $rwg
    "End of processing"

    Here is the test data that I played with. Save it as a .reg file and import it into your registry. 

    Windows Registry Editor Version 5.00
    [HKEY_CURRENT_USER\Software\Test]
    [HKEY_CURRENT_USER\Software\Test\SubKey1]
    "SubKey1Value"="first\\FOO2\\something"
    "SubKey1DWord"=dword:00099999
    [HKEY_CURRENT_USER\Software\Test\SubKey1\SubSubKey1]
    "SubSubKey1Value"="second\\foo2\\something"
    [HKEY_CURRENT_USER\Software\Test\SubKey2]
    "SubKey2Value"="snafu"
    "SubKey2Value2"="last\\fOo2\\something"

    • Marked as answer by Neo the 1 Sunday, October 14, 2018 3:04 PM
    Saturday, September 15, 2018 6:23 PM

All replies

  • "Search/Replace" in a value?  Just get the value and use the "-replace" operator.

    What is the issue?  

    Look up the docs for "Replace()" and "-replace" and note the difference.


    \_(ツ)_/

    Friday, September 14, 2018 9:13 PM
  • I want to set the new value back, how can I do that in PS way?

    Ignorance is blissful

    Saturday, September 15, 2018 9:34 AM
  • What does "get the new value back" mean? 

    To get a registry value just use Get-ItemProperty.

    help get-itemproperty -full

    Look at the examples.

    Why is this a problem or did you just copy the code rom somewhere?


    \_(ツ)_/

    Saturday, September 15, 2018 9:56 AM
  • I'm very new to PS. Maybe what seems very simple and direct is very difficult for me.

    Here is what I want to do:

    1. Enumerate subkeys under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components.

    2. For each subkey, get its subvalues.

    3. For each subvalue, test if the value contains string "mount\1".

    4. If it does, replace the string with something (an empty string).

    5. Write the replaced string back to the value.


    Ignorance is blissful

    Saturday, September 15, 2018 10:37 AM
  • What is the code you posted supposed to do?  Didn't you write it?

    Note that we cannot design custom scripts for you.  The forum is for answering specific questions and is not a free consulting forum.

    Look in the Gallery for a number of scripts that can search the registry.  You will also find many examples of how to access the registry from PowerShell.


    \_(ツ)_/


    • Edited by jrv Saturday, September 15, 2018 10:57 AM
    Saturday, September 15, 2018 10:50 AM
  • Sorry, I don't even know where is the Gallery.

    Ignorance is blissful

    Saturday, September 15, 2018 1:05 PM
  • Try this. Always test thoroughly first!!!! 

    function Analyze($keys)
    {  
     foreach ($k in $keys)
     {
       "Found key $k"
       
        # Now we can query the values in the key.
        $vals = Get-Item -path "Registry::$k"
        if ($vals.Count -gt 0)                                          # If we have subkeys
        {
            CheckValues $vals                    
        }
        
        # Let's recurse through all subkeys.
        $rwg = Get-ChildItem  -path "Registry::$k"  -ErrorAction SilentlyContinue    
        if ($rwg.Count -gt 0)                                          # If we have subkeys
        {
            Analyze $rwg                    
        }
     }
    }
    function CheckValues($vals)
    {   
     foreach ($v in $vals.getvaluenames())
     {
       "Found value: $v "
       $valdata =  $vals.GetValue($v)
       "Found value data: $valdata "
       if(($valdata.tostring()) -imatch $findme)       # Powershell is case sensitive, imatch is not
       {
           "We have a match!!!"
           $valdata = $valdata -replace $findme,$replaceme    #-replace is not case sensitive
           "New value data: $valdata "
           $rc = New-ItemProperty -Path "Registry::$vals"  -Name $v -Value $valdata ` -force   # remove -force or add -whatif to test
       }
     }  
    }
    # Powershell requires functions to be defined before inline code.
    $findme = "foO2"               
    $replaceme = "Success"
    $path = "HKEY_CURRENT_USER\Software\Test"
    "Enumerating $path"
    $rwg = Get-ChildItem  -path "Registry::$path"
    Analyze $rwg
    "End of processing"

    Here is the test data that I played with. Save it as a .reg file and import it into your registry. 

    Windows Registry Editor Version 5.00
    [HKEY_CURRENT_USER\Software\Test]
    [HKEY_CURRENT_USER\Software\Test\SubKey1]
    "SubKey1Value"="first\\FOO2\\something"
    "SubKey1DWord"=dword:00099999
    [HKEY_CURRENT_USER\Software\Test\SubKey1\SubSubKey1]
    "SubSubKey1Value"="second\\foo2\\something"
    [HKEY_CURRENT_USER\Software\Test\SubKey2]
    "SubKey2Value"="snafu"
    "SubKey2Value2"="last\\fOo2\\something"

    • Marked as answer by Neo the 1 Sunday, October 14, 2018 3:04 PM
    Saturday, September 15, 2018 6:23 PM
  • It's always good to show the error message.  You can set the value like this, without the whatif.  I think your way the key is read-only to setvalue() ?  (Might call opensubkey() with writable set to true?)  I'm not a big fan of the powershell registry provider.  To me, it should hand you key/value/data/type on a silver platter.  Note that "ls" or "get-childitem" doesn't give you the values/names in the top level registry key in PS 5.


    $key | set-itemproperty -name $name -value $value -whatif
    Saturday, September 15, 2018 6:34 PM
  • Sorry, I don't even know where is the Gallery.

    Ignorance is blissful

    A couple of suggestions.  Until you have learned PowerShell basics be very careful of code you see in forums or anywhere on the Interenet.  Much of it is very badly done and will not work as needed.

    The Gallery is in the list below along with resources useful for learning basic PowerShell:

    Please carefully review the following links to set your expectation for posting in  technical forums.

    This Forum is for Scripting Questions Rather than script requests


    \_(ツ)_/

    Saturday, September 15, 2018 7:44 PM