Search code examples
powershellregistry

Remove-ItemProperty does not seem to work with -LiteralPath


I'm trying to remove all values from a registry key. When dealing with the registry in PowerShell, I always pass LiteralPath, and it works fine everywhere except for Remove-ItemProperty.

This does not work as I expected: Remove-ItemProperty -LiteralPath 'HKCU:Delete_all_values' -Name *

but the regular -Path works: Remove-ItemProperty -Path 'HKCU:Delete_all_values' -Name *

Official docs are silent on this matter. Any suggestions on what I'm doing wrong?


Solution

  • What you're really looking for is Clear-Item - it'll remove all values but leave the key and any subkeys intact:

    Clear-Item -LiteralPath HKCU:\Delete_all_values
    

    Why doesn't -Name * work with -LiteralPath?

    Using -LiteralPath causes the *-ItemProperty provider cmdlets to suppress all wildcard expansion - including for property names:

    Get-ItemProperty -Path HKCU:\Delete_all_values -Name *         # returns all properties
    Get-ItemProperty -LiteralPath HKCU:\Delete_all_values -Name *  # returns no properties (unless you have one with the literal name *)
    

    You will observe the same behavior if you pipe a registry item, as PowerShell will bind the key's full provider path to -LiteralPath by default:

    # returns no properties (unless you have one with the literal name *)
    Get-Item HKCU:\Delete_all_values |Get-ItemProperty -Name * 
    

    Explicitly passing the value names to -Name will solve the problem:

    $targetKey = Get-Item -LiteralPath HKCU:\Delete_all_values
    
    # piping a RegistryKey instance will also cause binding against -LiteralPath
    $targetKey |Remove-ItemProperty -Name $targetKey.GetValuesNames()
    

    At which point you might as well just use Clear-Item