Home > Net >  Powershell how to find the property type of a registry item property
Powershell how to find the property type of a registry item property

Time:05-26

I've found several examples showing how to get, set, and create registry keys as well as their properties and values. I need to find what property type a registry key property has (DWord, String, Multistring etc.)

If I do Get-ItemProperty I can fetch the values of a property, like so:

PS C:\> Get-ItemProperty "HKLM:\SOFTWARE\MySoftware\MyKey\" -Name MyProperty


MyProperty    : MyValue
PSPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\MySoftware\MyKey\
PSParentPath  : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\MySoftware
PSChildName   : MyValue
PSDrive       : HKLM
PSProvider    : Microsoft.PowerShell.Core\Registry

However, this does not tell me if the value of MyProperty is a string, a DWord, a multistring, or whatever else it might be. The only way I've found to get that information is to pipe it to Get-Member, because the Definition tells me what type it is:

PS C:\> Get-ItemProperty "HKLM:\SOFTWARE\MySoftware\MyKey\" -Name MyProperty | Get-Member
                                                                                                                                                                                                                                                                 

TypeName: System.Management.Automation.PSCustomObject

Name            MemberType    Definition
----            ----------    ----------
Equals          Method        bool Equals(System.Object obj)
GetHashCode     Method        int GetHashCode()
GetType         Method        type GetType()
ToString        Method        string ToString()
PSChildName     NoteProperty  string PSChildName=MyKey
PSDrive         NoteProperty  PSDriveInfo PSDrive=HKLM
PSParentPath    NoteProperty  string PSParentPath=Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\MySoftware
PSPath          NoteProperty  string PSPath=Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\MySoftware\MyKey\
PSProvider      NoteProperty  ProviderInfo PSProvider=Microsoft.PowerShell.Core\Registry
MyProperty      NoteProperty  string MyProperty=MyValue

I can then select the property value, split the string and fetch the first object, like so:

PS C:\> ((Get-ItemProperty "HKLM:\SOFTWARE\MySoftware\MyKey\" -Name MyProperty | Get-Member | Where-Object{$_.Name -eq "MyProperty"}).Definition -split " ")[0]

string

I verified that this gives int when I do this with a DWord attribute, but this just doesn't feel like the proper way of finding this information. Is there another, more proper or robust way to find what property type a specific registry key property has?

EDIT: I also just verified that both String and ExpandString return "string" here so there are edge cases where even the above solution does not work.

CodePudding user response:

You can get the type of a property using the .GetType() method:

$value = (Get-ItemProperty 'HKLM:\SOFTWARE\MySoftware\MyKey' -Name MyProperty).MyProperty
$value.GetType().Name   # outputs e. g. "String"

To explicitly test for a given type, use the -is operator:

$value -is [string]   # outputs True if $value is a string

To see how each registry value type maps to a PowerShell type, I've created a registry key that contains values of all possible types and ran the following script:

$props = Get-ItemProperty "HKCU:\test"
$props.PSObject.Properties.Where{ -not $_.Name.StartsWith('PS') }.ForEach{
    [pscustomobject]@{ 'Reg Type' = $_.Name; 'PS Type' = $_.Value.GetType() }
}

Output:

Reg Type      PS Type
--------      -------
REG_DWORD     System.Int32
REG_SZ        System.String
REG_QWORD     System.Int64
REG_BINARY    System.Byte[]
REG_MULTI_SZ  System.String[]
REG_EXPAND_SZ System.String

As you can see both REG_SZ and REG_EXPAND_SZ map to System.String, so you can't differentiate these when you read them using Get-ItemProperty. Instead you would have to use the .NET method RegistryKey.GetValueKind():

$key = Get-Item 'HKLM:\SOFTWARE\MySoftware\MyKey'   # $key is of type RegistryKey
$key.GetValue('MyProperty')      # Output the value
$key.GetValueKind('MyProperty')  # Output the registry type of the value

This outputs "ExpandString" for registry type REG_EXPAND_SZ. For other possible values see RegistryValueKind enum.

  • Related