Search code examples
powershellregistry

Normalize registry path in PowerShell


There are several ways to reference a registry key in PowerShell:

  • Using a builtin PSDrive, such as HKCU or HKLM, for example HKLM:\SOFTWARE\Wow6432Node.
  • Using a user-created PSDrive, such as HKCR for HKEY_CLASSES_ROOT.
  • Using the Registry:: provider: Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node.
  • Maybe some other ways I'm not aware of.

Given a string in one of the above formats, how can I get a "normalized" registry key path (with the hive part expanded, HKCU => HKEY_CURRENT_USER etc) efficiently? Is there a way to do it without messing with regular expressions?


Solution

  • Use Convert-Path to convert an existing registry path or any other path to a PowerShell provider path (aka a native path, typically in the format of the underlying OS API).

    > Convert-Path HKLM:\SOFTWARE\Wow6432Node
    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
    
    > $null = New-PSDrive -Name HKCR -Root HKEY_CLASSES_ROOT -PSProvider Registry
    > Convert-Path HKCR:\Software
    HKEY_CLASSES_ROOT\Software
    
    > Convert-Path Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
    HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node
    
    > Convert-Path HKLM:\DoesntExist
    Convert-Path: Cannot find path 'HKLM:\DoesntExist' because it does not exist.
    

    In case the path does not exist, you can use code like this:

    > $PSCmdlet.GetUnresolvedProviderPathFromPSPath('HKLM:\DoesntExist')
    HKEY_LOCAL_MACHINE\DoesntExist
    

    Note that the $PSCmdlet is an automatic variable that requires an advanced function (aka cmdlet) context. If you need to call it from the console, where the variable is not available, you can use the automatic variable $ExecutionContext instead:

    > $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('HKLM:\DoesntExist')
    HKEY_LOCAL_MACHINE\DoesntExist