I'm only finding stuff on how to change the attribute values of a XML element here on StackOverflow.
But how do we change the value of the element itself using PowerShell?
I currently have:
XML
<Task>
<Settings>
...
</Settings>
<Actions Context="Author">
<Exec>
<Command>blablabla</Command>
<Arguments>CHANGETHISVALUE</Arguments>
</Exec>
</Actions>
</Task>
SCRIPT
$filePathToTask = C:\Task.xml
$xml = New-Object XML
$xml.Load($filePathToTask)
$element = $xml.SelectSingleNode("//Arguments")
$element.InnerText("newtext")
$xml.Save($filePathToTask)
However, I can't seem to use methods on the last variable. What am I doing wrong?
Edit
The error that I'm getting is You cannot call a method on a null-valued expression
I think my problem lies at:
$ElementToChange = $xml.SelectSingleNode("//Arguments")
Which stays null, but I have tried methods like .SelectNodes
and playing around with the //Arguments
tag but still no success
InnerText
is a property, not a method. It's used like this:
$element.InnerText = "newtext"
Also, I suspect that your original data (unlike the XML sample you posted) uses namespaces. AFAICS that's the only possible reason why $xml.SelectSingleNode('//Arguments')
would return an empty result.
XML files exported from the Windows Task Scheduler definitely are namespaced:
<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task">
<!-- ... -->
</Task>
Namespaces are not like other node attributes and affect not only the node itself, but also its child nodes. For selecting nodes from an XML with namespaces you need a namespace manager:
$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
$nsm.AddNamespace('ns', $xml.DocumentElement.NamespaceURI)
$element = $xml.SelectSingleNode('//ns:Arguments', $nsm)
When I run:
$filePathToTask = "C:\temp\Task.xml"
$xml = New-Object XML
$xml.Load($filePathToTask)
$element = $xml.SelectSingleNode("//Arguments")
$element.InnerText = "New Text"
$xml.Save($filePathToTask)
And re-check the output, I do see the updated value:
<Task>
<Settings>
</Settings>
<Actions Context="Author">
<Exec>
<Command>blablabla</Command>
<Arguments>New Text</Arguments>
</Exec>
</Actions>
</Task>
I enclosed the path in quotes, otherwise I was getting an error on the load line. That's good practice anyway, since the parameter for the Load method takes string filepath as input. Then as Ansgar mentions, use the assignment operator ("=") to set the new value in memory, then dump to file.
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