Custom Types and pstypenames behavior

I have something here that’s been driving me nuts. Here’s an example function:

[pre]
function Get-Wibble {
if (-not (Get-TypeData -TypeName ‘Wibble’)) {
Update-TypeData -TypeName ‘Wibble’ -DefaultDisplayPropertySet Colour, Date
}
$Name = @(‘Red’,‘Yellow’,‘Puce’,‘Red’,‘Yellow’,‘Puce’)
$Date = @(‘16/03/19’,‘16/03/19’,‘16/03/19’,‘17/03/19’,‘17/03/19’,‘16/03/19’)
0…5 | ForEach-Object {
[pscustomobject] @{
PSTypeName=‘Wibble’
Colour = $Name[$]
Date = $Date[$
]
Message = “Something random $_”
}
}
}
[/pre]

This works as expected with Get-Member, the typename is “Wibble”. However, If I type:

[pre]
(get-wibble).pstypenames
[/pre]

I expected to see the custom type at the top of the list, but I just get the types you’d normally see for a custom object. What is going on here?
 

Are you sure you are going about this in a prudent way?

See these for possible edification:

https://jrich523.wordpress.com/2012/01/20/powershell-custom-objects-with-format-files
https://powershellstation.com/2016/05/22/custom-objects-and-pstypename
https://learn-powershell.net/2012/03/02/working-with-custom-types-of-custom-objects-in-powershell
https://learningintheopen.org/2011/12/22/microsoft-powershell-list-all-the-properties-for-an-object
https://rkeithhill.wordpress.com/2007/10/28/powershell-quicktip-using-pstypenames-to-see-the-typename-and-inheritance-chain
https://poshoholic.com/2010/06/21/powershell-quick-tip-getting-all-of-the-members-of-an-object

Thanks. I’m not sure I understand the comment about prudent. You link to articles I’ve read that are using the pstypenames method.

Let me try again with two examples. I’m asking why, in terms of enumerating the type names of the custom object, does this not work:

[pre]
$Name = @(‘Red’,‘Yellow’,‘Puce’,‘Red’,‘Yellow’,‘Puce’)
$Date = @(‘16/03/19’,‘16/03/19’,‘16/03/19’,‘17/03/19’,‘17/03/19’,‘16/03/19’)
$test = 0…5 | ForEach-Object {
[pscustomobject] @{
PSTypeName=‘Wibble’
Colour = $Name[$($)]
Date = $Date[$($
)]
Message = “Something random $_”
}
}
$test.pstypenames[/pre]

Whilst this does work:
[pre]
$test2 = [pscustomobject] @{
PSTypeName=‘Wibble’
Colour = $Name[$(0)]
Date = $Date[$(0)]
Message = “Something random $_”
}
$test2.pstypenames[/pre]

PSTypenames is a hidden property that’s not as easily-found and not even in the same form as you declare it in that syntax. It receives special treatment, for convenience. That gets mapped to $test2.PSObject.TypeNames, which you’ll find is actually a collection of different values (you can even .Add() a new value in if you like after creating the object). PSTypeNames is a shortcut specifically for PSCustomObject to allow you to declare the primary type name to use when creating it. Otherwise you wouldn’t be able to, and would always have to add it after creating the object.