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()