Search code examples
powershellregistry

Filter and delete Registry values with Where-Object


I'm not sure why I'm finding this so difficult. From under a particular registry key, I'd like to query certain registry-values based on their data (not name), and delete the resulting registry-values.

For example:

screenshot of registry

How would I delete any values in this key that contain, let's say, "foo". I can list the registry values with Get-ItemProperty 'HKCU:\Software\Policies\Google\Chrome\RestoreOnStartupURLs', but it intermingles some rubbish along with the actual data:

1            : http://foo.example.com
2            : http://bar.example.com
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Policies\Google\Chrome\RestoreOnStartupURLs
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Policies\Google\Chrome
PSChildName  : RestoreOnStartupURLs
PSDrive      : HKCU
PSProvider   : Microsoft.PowerShell.Core\Registry

I was trying to pipe to Where-Object but can't find a query that works. And then I'd need a Remove- cmdlet that can handle the result. Anyone have any ideas?


Solution

  • I think this issue is a matter of stepping back and taking a look at the bigger picture. You're focused on the value or a property, and how to get that property name that you aren't taking into consideration that the property is just a part of a larger object, the key. Let's work with the key's object and see where that gets us. I'm going to assign the path to a variable, because we'll use it later.

    $KeyPath = 'HKCU:\Software\Policies\Google\Chrome\RestoreOnStartupURLs'
    $ChromeKey = Get-Item $KeyPath
    

    Now that object is Microsoft.Win32.RegistryKey object with some helpful methods built in to it. The one that we are concerned with for your needs is called GetValueNames(), which (unsurprisingly) gives you the names of the values, which for you should return:

    (default)
    1
    2
    

    So, we pipe that into a Where statement that gets the actual values for those names, matches them for Foo, and then we act upon them. First things first, getting those properties that we are concerned with:

    $ChromeKey.GetValueNames() | Where {$ChromeKey.GetValue($_) -match "foo"}
    

    That command should return one value, 1. Then just use that as needed with something like Remove-ItemProperty...

    $ChromeKey.GetValueNames() | Where {$ChromeKey.GetValue($_) -match "foo"} | ForEach{ Remove-ItemProperty -Path $KeyPath -Name $_ }
    

    Done, that will find all values of your key that match 'foo' and remove them from the key.