Reputation: 6863
I can use Get-Item
with folders, files and registry keys, and the type of the object I get back will make sense; [System.IO.DirectoryInfo]
, [System.IO.FileInfo]
or [Microsoft.Win32.RegistryKey]
.
But with registry properties, what using Get-ItemProperty
returns is a [System.Management.Automation.PSCustomObject]
. Is this because there is no dedicated type for registry property? That seems odd. But my Google-Fu is not turning anything up.
My use case is this, I am doing a series of Copy and Move tasks, with all four item types potentially getting copied or moved, and I want to implement an option to rename an existing destination rather than overwriting or failing. And exactly what the rename options are depends on the object type. And from a readability standpoint, PSCustom Object
or a simple else
for RegistryProperty is a bit ugly. So, looking for a way to get the property back as a type with a more obvious name, so when I look at the code again in 12 months it makes some sense.
Upvotes: 1
Views: 2743
Reputation: 437062
Get-ItemProperty
returns what is conceptually a registry value object: a property of a registry key that has a name and a - uh... - value (the named value object's data).
The .NET registry API has no type to represent such a value object - instead, it allows access via the registry key type's .GetValue($valueName)
(to get a specific value object's data[1]) and .GetValueNames()
methods (to get the list of all value names).
The PowerShell implementers apparently chose not to implement their own .NET type, and chose to use PowerShell's general-purpose, dynamic "property-bag" type, [pscustomobject]
[2] to model these value objects.
If you want to avoid the [pscustomobject]
instances that Get-ItemProperty
returns, you can use Get-Item
instead, which returns a Microsoft.Win32.RegistryKey
instance, i.e. an instance of the .NET type representing a key, on which you can invoke the methods mentioned above.
As an aside: If you're just interested in a given value object's data, you can use the PSv5+
Get-ItemPropertyValue
cmdlet (e.g.
Get-ItemPropertyValue HKCU:\Console -Name LineWrap
directly returns the [int]
data of the targeted value).
[1] Additionally, as js2010's answer shows, the .GetValueKind()
method returns an enum
value that identifies a given value object's registry-specific data type. These types imply what .NET types are used to represent them, as returned by .GetValue()
, but in some cases have no direct equivalent (ExpandString
, MultiString
, Unknown
) and require additional work to interpret them correctly.
[2] It is possible - but wasn't done in this case - to assign (one or more) self-chosen type names to [pscustomobject]
instances, which PowerShell reflects as the type name in Get-Member
output (only the first, if there are multiple) and which it respects for ETS type definitions and format-data definitions. However, such pseudo types are not accessible as type literals; e.g.: $obj = [pscustomobject] @{ PSTypeName = 'MyType'; prop = 'foo' }
allows you test for this type name with $obj.pstypenames -contains 'MyType'
, but not with $obj -is [MyType]
. That said, you can base parameter declarations on them, via the [PSTypeName()]
attribute.
Upvotes: 2
Reputation: 27418
There is a way to get the type of the properties:
$key = get-item hkcu:\key1
$key.GetValueKind('value1')
DWord
Upvotes: 1