When explicitly casting my new object (see the first line of code), my newly created EntityReference gets stored without being wrapped in a PSObject, and so serializing it works just fine:
$entityRef1 = [Microsoft.Xrm.Sdk.EntityReference](new-object Microsoft.Xrm.Sdk.EntityReference("businessunit", [System.Guid]::NewGuid()))
$unit = new-object Microsoft.Xrm.Sdk.Entity("businessunit")
$unit.Attributes["parentbusinessunitid"] = $entityRef1
$unit.Attributes["parentbusinessunitid"].GetType() # Produces "EntityReference"
# Serialize $unit including the entityRef, and write its xml representation
$serializer = New-Object System.Runtime.Serialization.DataContractSerializer($unit.GetType())
$stream = New-Object System.IO.MemoryStream
$serializer.WriteObject($stream, $unit)
$stream.Flush()
$stream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = New-Object System.IO.StreamReader($stream)
$reader.ReadToEnd()
However, when I don't use the cast:
$entityRef1 = (new-object Microsoft.Xrm.Sdk.EntityReference("businessunit", [System.Guid]::NewGuid()))
PowerShell complains when I want to serialize it:
Exception calling "WriteObject" with "2" argument(s): "Type 'System.Management.Automation.PSObject' with data contract name 'PSObject:http://schemas.datacontract.org/2004/07/System.Management.Automation' is not expected.
Now, I've read Why does Get-Date seem to return DateTime objects, but the BinarySerializer indicate it returns a PSObject?, and it would appear that this is the same problem....
except that I use PowerShell 3.0 ($PSVersionTable.psversion produces version 3.0.-1.-1) and that the 'faulty' code fragment from that post works fine in my PowerShell environment...
In that post it is suggested that the new DLR-based engine from PowerShell 3 should no longer cause these problems, so were they being too optimistic about that, or have I run into something else?
Edit: The code below produces the same behaviour without being dependant on the CRM SDK. With the cast, PowerShell complains about not being able to serialize System.UriBuilder, whereas without the cast, it complains about getting a System.Management.Automation.PSObject instance:
# $uriBuilder = [UriBuilder](New-Object UriBuilder)
$uriBuilder = (New-Object UriBuilder)
$dict = new-object Hashtable
$dict["mykey"] = $uriBuilder
$dict["mykey"].GetType() # Produces "UriBuilder"
# Serialize $dict including the uriBuilder, and write its xml representation
$serializer = New-Object System.Runtime.Serialization.DataContractSerializer($dict.GetType())
$stream = New-Object System.IO.MemoryStream
$serializer.WriteObject($stream, $dict)
$stream.Flush()
$stream.Seek(0, [System.IO.SeekOrigin]::Begin)
$reader = New-Object System.IO.StreamReader($stream)
$reader.ReadToEnd()