Home > Software design >  Get-ItemProperty with Registry, returned object type
Get-ItemProperty with Registry, returned object type

Time:11-15

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.

CodePudding user response:

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) 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][1] 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] 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.

  • Related