Create XML in PowerShell

Before we start if we don’t have a XML file, we can create one:

Set-Content .\test.xml '<?xml version="1.0" encoding="utf-8"?><root/>'

Set-Content is a powershell cmd-let to write to a file.

The first element is the prolog element 1: <?xml version="1.0" encoding="utf-8"?>. The W3C Recommendation describes the prolog as version number, encoding declaration.

If we want to load it and write to it, it must have at least a root element, in this example it is <root> but it can be anything such as <catalog>, <company>, <store>, or even <zoo>.

Read XML in PowerShell

We can read the XML file in PowerShell by the following:

$xml = [xml](Get-Content '.\input.xml')

This will allow us to access the different nodes (i.e., elements, attributes, text, etc2) in the XML document.

Update/Edit XML in PowerShell

Suppose we have the following XML file input.xml:

<?xml version="1.0" encoding="UTF-8"?>
<rootElement attribute="value 1">
  <subElement>first</subElement>
  <subElement>second</subElement>
</rootElement>

Update Attribute

This will udpate the attribute

## node = <rootElement ...>
$node = $xml.rootElement

# edit attribute node of rootElement
# <rootElement attribute="...">
$node.attribute = 'value 2'

Attributes can be named anything, so if our attribute was named version (e.g., <rootElement version="1.0">):

$node.version = "2.0.0"

another example:

# $node = <cat name="Taby">
$node.name = "Simba"

another example:

# $node = <employee id="123">
$node.id = "456"

Update InnerText

Let’s go back to the original example:

<?xml version="1.0" encoding="UTF-8"?>
<rootElement attribute="value 1">
  <subElement>first</subElement>
  <subElement>second</subElement>
</rootElement>

How do we update the text in the subElement element? This is called InnerText. First we select the nodes, then we can change the values.

$nodes = $xml.rootElement.SelectNodes('subElement')
$nodes[0].InnerText = '1st'
$nodes[1].InnerText = '2nd'

we can also use a loop:

# can use foreach
$nodes = $xml.rootElement.SelectNodes('subElement')
foreach ($node in $nodes)
{
    $node.InnerText = "Same text for each node"
}

Add a new element

To add an element to our root node, we can do the following:

# Append (or add) a new element
$newNode = $xml.CreateElement("subElement")
$newNode.InnerText = 'Third'

$xml.DocumentElement.AppendChild($newNode)

Delete an element

# Delete first element
$node = $xml.rootElement.SelectSingleNode('subElement')

# do we have a first element? if so, delete it
if ($node -ne $null)
{
    $node.ParentNode.RemoveChild($node)
}

Output the XML

Finally, to save the changes use $xml.Save with the path we want to save the file to.

$xml.Save('.\output.xml')