Yes, this is another PSObject unwrapping bug, although after I pondered it, I realised it is known about by the PowerShell team and will likely remain a "won't fix" for a while.
Before you curse them, think about this: When PSObject's (everything implicitly typed is) are passed to .NET methods, they are unwrapped by the binder, but it does not recurse into enumerables or examine properties to see if things need to be unwrapped or not. Frankly, it cannot know at this point whether a property typed as object (for example) containing a PSObject, should be unwrapped or not, so it does nothing. Only first-level instances are unwrapped, if required.
I think the real bug here - is that the uribuilder instance is not unwrapped when it is assigned to the hashtable key.
The golden rule: PowerShell will never unwrap the PSObject if the assignment target is object.
So, the workaround is either cast at the creation, or at the assignment point:
$ht["foo"] = [uribuilder]$builder
The New-Object cmdlet is the cause of the wrapping. Once the cmdlet passes the instance to PSCmdlet.WriteObject, the wrapper is applied.