$xml = [xml] '<node>foo</node>'
function foo2 { return "foo2" }
# all of these fail with the message:
# **Cannot set "foo" because only strings can be used as values to set XmlNode properties.**
$xml.node = foo2
$xml.node = foo2 -as [string] # because of this issue[1]
$xml.node = (foo2)
# these work
$xml.node = (foo2).tostring()
$xml.node = (foo2) -as [string]
$xml.node = [string] (foo2)
# yet, these two statements return the same value
(foo2).gettype()
(foo2).tostring().gettype()
1: PowerShell functions return behavior
Got some confirmation from the PowerShell team on this one. This appears to be a bug in the XML adapter. If you look at the object that is spit out by foo2 in a debugger it is a PSObject. If you don't use the return keyword and instead just output the string "foo2" then the function returns a string object.
The bug in the XML adapter is that it is not unwrapping the PSObject to get at the base object. As a result when it tries to assign the PSObject to $xml.node it fails. For now, as a workaround, you can manually unwrap the psobject like so (or just cast to [string]):
$xml = [xml] '<node>foo</node>'
function foo2 { return "foo2" }
$xml.node = (foo2).psobject.baseobject
$xml
node
----
foo2
Depending on the context, functions may return an array (of length 1) where your expected result is at index 0 in the array. To ensure you always get a scalar if a single element is returned wrapped in an array, use the following syntax:
$xml.node = $( myfunc )
Hope this helps,
-Oisin
p.s. I know others cannot repro this, and nor can I, but I suspect your demo code is cut out from some other, larger script.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With