This is an unsuccessful bug in an extended type V2 system where a psobject can be created around a base .NET type. This can happen when adding elements to an object or when accessing a missing property. This can also happen when you access the psobject property on an IIRC object, for example. $newId.psobject . When you stay in PowerShell, this usually does not cause any problems.
Update: This is not a .NET calling problem. Some quick .NET test code shows that it gets a deployed object for a property setting tool. Looking at it with Trace-Command , it looks like an error in the PowerShell XmlNodeAdapater :
DEBUG: ETS Information: 0 : Method Enter PSObject..ctor():object = System.Management.Automation.RuntimeException: Cannot set "Id" because only strings can be used as values to set XmlNode properties. ---> System.Management.Automation.SetValueException: Cannot set "Id" because only strings can be used as values to set XmlNode properties. at System.Management.Automation.XmlNodeAdapter.PropertySet(PSProperty property, Object setValue, Boolean convertIfPossible) at System.Management.Automation.Adapter.BasePropertySet(PSProperty property, Object setValue, Boolean convert) at System.Management.Automation.PSProperty.SetAdaptedValue(Object setValue, Boolean shouldConvert) at System.Management.Automation.PSProperty.set_Value(Object value) at System.Management.Automation.PropertyReferenceNode.SetValue(PSObject obj, Object property, Object value, ExecutionContext context) --- End of inner exception stack trace --- at System.Management.Automation.PropertyReferenceNode.SetValue(PSObject obj, Object property, Object value, ExecutionContext context) at System.Management.Automation.AssignablePropertyReference.SetValue(Object value, ExecutionContext context) at System.Management.Automation.AssignmentStatementNode.Execute(Array input, Pipe outputPipe, ExecutionContext context) at System.Management.Automation.StatementListNode.ExecuteStatement(ParseTreeNode statement, Array input, Pipe outputPipe, ArrayList& resultList, ExecutionContext context)
One way to ensure that you always get a base .NET object:
$xmlDoc.root.ComponentRef.Id = $newId.psobject.baseobject
The good news is that this problem is fixed in V3, for example:
PS> $xmlDoc = [xml]@" <root> <ComponentRef Id="a" /> </root> "@ PS> $newId = "b" PS> $newId.Length 1 PS> $newId.psobject.typenames System.String System.Object PS> $xmlDoc.root.ComponentRef.Id = $newId PS> $xmlDoc | format-xml
Keith Hill Apr 27 '12 at 23:19 2012-04-27 23:19
source share