Markus
Markus

Reputation: 11

Is there a way to search for Registry Keys and Values, export and delete them

Im searching for an way to delete the Registry Keys/Values from remote printers, the Keys/Values include the name "(umgeleitet", cause they are slowing down the whole RDP-Sessions. But I want to backup them just in case something gets deleted that shouldn't

I have already tried doing it with Get-ChildItem and Get-ItemProperty

$Folder = "C:\Users\Public\Documents\Backup"
Reg export HKU "$Folder\Backup.reg"
Get-ChildItem -path REGISTRY::HKEY_USERS\ -Recurse | where { $_.Name -match "(umgeleitet *)"}>> "$Folder\Log.log"
Get-ChildItem -path REGISTRY::HKEY_USERS\ -Recurse | where { $_.Name -match "(umgeleitet *)"} | Remove-Item -Force -Recurse

The code above doesn't delete the Values just the Keys.

Upvotes: 0

Views: 5400

Answers (3)

mklement0
mklement0

Reputation: 437090

Exporting:

Your question already shows the proper solution use: reg.exe export <key-path> <file> to export a registry key's subtree to a file.

Note that if you wanted to export the specific keys found as shown below, you'll have to call reg export for each, to separate files, given that reg export supports only a single target key path, and doesn't support appending to existing files.

Specifically, you could pipe the command below to reg export as follows, to create file1.reg, file2.reg, ... files:

$i = 1
Get-ChildItem -path REGISTRY::... | ForEach-Object { 
  reg.exe export $_.Name "file$(($i++)).reg"
}

Locating keys via matching against their value names:

Get-ChildItem -path REGISTRY::HKEY_USERS\ -Recurse | Where-Object { 
  $_.GetValueNames() -match '\(umgeleitet .*\)'
}

Note the need to use a proper regular expression with -match, in which literal ( and ) must be \-escaped, and in which .* represents any sequence of characters. By contrast, what you used, (umgeleitet *), is a wildcard expression, to be used with -like (though note that wildcard expressions must match the entire input string).

If you wanted to match against value data, a little more work would be needed.


To remove the keys found, simply pipe the above to Remove-Item, as in your question:

... | Remove-Item -Force -Recurse

Upvotes: 1

js2010
js2010

Reputation: 27428

Here's a script alternative to get-itemproperty:

# get-itemproperty2.ps1
# get-childitem skips top level key properties, use get-item for that

# example pipe to set-itemproperty:
# ls -r hkcu:\key1 | get-itemproperty2 | where value -match value | 
#   set-itemproperty -value myvalue -whatif

param([parameter(ValueFromPipeline)]$key)

process { 
  $valuenames = $key.getvaluenames() 

  if ($valuenames) { 
    $valuenames | foreach {
      $value = $_
      [pscustomobject] @{
        Path = $key -replace 'HKEY_CURRENT_USER',
          'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
        Name = $Value
        Value = $Key.GetValue($Value)
        Type = $Key.GetValueKind($Value)
      }
    }
  } else {
    [pscustomobject] @{
      Path = $key -replace 'HKEY_CURRENT_USER',
        'HKCU:' -replace 'HKEY_LOCAL_MACHINE','HKLM:'
        Name = ''
        Value = ''
        Type = ''
    }
  }
}

Then you can do things like:

ls -r hkcu:\key1 | .\get-itemproperty2 | where value -match value

Path                 Name  Value     Type
----                 ----  -----     ----
HKCU:\key1\key2      name2 myvalue String
HKCU:\key1\key2\key3 name3 myvalue String


ls -r hkcu:\key1 | .\get-itemproperty2 | where value -match value | Remove-ItemProperty -WhatIf
What if: Performing the operation "Remove Property" on target "Item: HKEY_CURRENT_USER\key1\key2 Property: name2".
What if: Performing the operation "Remove Property" on target "Item: HKEY_CURRENT_USER\key1\key2\key3 Property: name3".

Upvotes: 0

FoxDeploy
FoxDeploy

Reputation: 13537

I rewrote the registry query a tiny bit, to match on the PSChildName property, which is shorter and will match a bit faster.

$matchingRegKeys = Get-ChildItem -path REGISTRY::HKEY_USERS\ -Recurse | where PSChildName -match "(umgeleitet *)"

You'll notice I also placed the results into a variable so we can iterate through them with a simple ForEach loop.

ForEach ($regkey in $matchingRegKeys){
    "Removing $($regkey.Name)" | Tee-Object -Append "$Folder\Log.log"
    $regkey >> "$Folder\Log.log"
    Remove-Item -Path $regkey.PSPath
}

The Tee-Object command tells PowerShell to both write the output to the screen and also place the items appended into the filepath specified. Then we write the regkeys values out as well to the file.

Finally, we call Remove-Item and provide the $regkey.PSPath property, which corresponds to the full path of the key, so you can clear it out and any values.

In operation :

Removing HKEY_CURRENT_USER\Software\umgeleitet
Removing HKEY_CURRENT_USER\Software\umgeleitet2
Removing HKEY_CURRENT_USER\Software\umgeleitetTheAwakening

And a snip of the log file created:

Removing HKEY_CURRENT_USER\Software\umgeleitet
    Hive: HKEY_CURRENT_USER\Software
Name                           Property                                                                                           
----                           --------                                                                                           
umgeleitet                     SomeTestValue : true

The completed code

$Folder = "C:\Users\Public\Documents\Backup"
Reg export HKU "$Folder\Backup.reg"
$matchingRegKeys = Get-ChildItem -path REGISTRY::HKEY_USERS\ -Recurse | where PSChildName -match "(umgeleitet *)"

ForEach ($regkey in $matchingRegKeys){
    "Removing $($regkey.Name)" | Tee-Object -Append "$Folder\Log.log"
    $regkey >> "$Folder\Log.log"
    Remove-Item -Path $regkey.PSPath
}

Upvotes: 0

Related Questions