Creating Custom XML in PowerShell

Posted on December 29, 2016 by Jeff Hicks in PowerShell with

PowerShell-Text-Purple-hero

I hope you’ve been following along in our exploration of working with XML in PowerShell. If you are just jumping in, I encourage you to take a few minutes to read the previous articles in this series. In the last article, I demonstrated a number of ways to get PowerShell output into an XML file. But sometimes, you have to take matters into your own hands to create the exact XML format that you need. Before you begin, I want to re-iterate the importance of planning ahead. How will you be using the XML files? Will you be re-using them in a PowerShell session? Will they be processed by some external XML-driven application or process? Will humans need to interact with them or machines? I’m going to demonstrate several techniques but understand that there is no single best practice.

 

 

In the previous article, I introduced you to ConvertTo-Xml. Because the cmdlet doesn’t immediately create a file, you have the option of modifying the XML first. Here’s one scenario.

I have a list of computers.

I want to get disk information from each computer and save the results to an XML file. This XML file will be consumed by an external trend reporting process. In addition to the information I get back from Get-CimInstance, I need to include at least one custom property and I want to change a few other things in the file. Here’s my code to create an XML stream and save it to a variable.

I am excluding any of the CIM system properties and using Add-Member to create a custom property. The XML stream will include my custom property.

Converted XML

Converted XML (Image Credit: Jeff Hicks)

I know that eventually, I will want to change ‘PSComputername’ and instead of Object and Objects, use more meaningful node names.

The variable, $xmlStream is actually an array of different XML elements. Item 0 is the XML declaration.

The XML directive

The XML directive (Image Credit: Jeff Hicks)

Technically, the declaration should include an encoding directive, so I’ll simply assign a new value.

Next, instead of ‘Objects’ and ‘Object’, I want the outer node to be ‘Disks’ and ‘Disk’. The outer tags are simple enough to change.

Don’t forget that XML is case-sensitive, so your tags must match. Next, I need to modify each of the nodes, replacing key pieces of text. I’ll use a FOR loop to go through each disk element.

The last replacement is done with a fancy regular expression pattern utilizing a lookback, so I can change both <Object> and </Object> with a single line of code. But now my array of XML elements is properly formatted. All that remains is to send the results to a file.

Note that I encoded the file to match the XML declaration. To simplify the process I would wrap all of this up in a PowerShell function or a script.

Another approach might be to convert everything to a single string.

I can easily make the same kind of adjustments.

There are additional ways to create custom XML from scratch, but I think this may be enough for now. There’s plenty here for you to experiment with and try on your own. And don’t worry, I’ll address how to bring these custom files back into PowerShell in a future article. As always, comments and questions are welcome.

Tagged with , ,

Register for this upcoming webinar on Petri.com
Webinar: Accelerate Smart Factory ROI with Deloitte and HPE’s Digital IoT

Join HPE and Deloitte for a discussion on how to take advantage of IT and OT convergence to deliver the Factory of the Future

Tuesday, October 24, 2017
at 2 p.m. EST

Register for this upcoming webinar on Petri.com
Webinar: Accelerate Smart Factory ROI with Deloitte and HPE’s Digital IoT

Join HPE and Deloitte for a discussion on how to take advantage of IT and OT convergence to deliver the Factory of the Future

Tuesday, October 24, 2017
at 2 p.m. EST