That’s… not quite correct, although I can understand the confusion from how PS plays fast and loose with the easy conversions!
Although both methods of creating a PSObject have the same result, and both are created with hashtables, neither are in any way a hashtable after the PSObject is created, and they were never each a hashtable array. The hashtable’s key/value pairs are pulled apart and converted into PSPropertyInfo objects in the PSObject’s internal `Properties` collection.
You can examine this in a few ways, but here is one:
$Object = [PSCustomObject]@{ Property1 = 10; Property2 = 15}
#Check out the properties directly; the true PSObject is hidden in PS as a secret '.PSObject' property of the stored object
$PropertyCollection = $Object.PSObject.Properties
# You probably won't guess what this actually is unless you already know ;)
$PropertyCollection.GetType()
# Each single "property" is actually a discrete object of its own, with its own metadata properties
$PropertyCollection
An important distinction should be made, however – all objects that you can work with in PowerShell are actually PSObjects, because everything you can interact with in PowerShell always come wrapped in a PSObject wrapper. It’s essentially a universal interface for all objects in PowerShell which enables the Extended Type System to add arbitrary properties and methods via Add-Member and other internal methods beyond what the .NET object types normally have.
For example, in .NET languages like C#, not all objects have a `Count` property (this is typically restricted to collection-type objects like arrays, dictionaries, and Lists). However, in PowerShell, the ETS adds a property named `Count` to every object (this was added somewhere between v3 and v5 of PowerShell, to my memory) in part to make it easier to work with PS’s array-unwrapping behaviour that can otherwise be a little annoying to work with at times.
PSObjects created with New-Object or with [PSCustomObject] are a bit different, though. They don’t have a base object, so they’re kind of an empty bag with whatever ETS properties you’ve elected to give them via the hashtable construction. They don’t retain the original hashtable in any way; in the above example you can see how all the key/value pairs from the hashtable are mapped to properties in the internal collection, but the hashtable’s own properties (e.g., `$hashtable.Keys`) are completely gone and not retained anywhere.
It’s for this reason that such PSObjects are sometimes referred to as a “property bag”.