Converting PowerShell to XML

PowerShell-Text-Purple-hero
Today we’ll continue looking at working with XML in PowerShell. Now, the title of this article might be a bit misleading, as we aren’t actually going to convert PowerShell to XML. But rather, I want to demonstrate different ways you can take results from a PowerShell expression or command and turn them into XML. This process is known as serialization and is a terrific technique for saving data that you can re-use later in PowerShell.
 

 
Because the XML format is hierarchical, it is a perfect vessel for storing all of the rich object information we get in PowerShell. But a word of caution. When you are considering turning the results of a PowerShell command into an XML document, the first question should be “How am I going to use the result?”  Do you plan on using the data in a PowerShell session? Do you need to use the file in an external XML-aware application? Does the file need to be easily read by a human? There are different tools and techniques you can employ depending on your requirements.

Export-CliXml

For the majority of your XML needs, I am expecting Export-Clixml to be your command of choice. This cmdlet is designed to take the output of any PowerShell expression, convert it to XML and save the results to a file. The primary purpose of this command is to create an XML document that you intend to bring back to life in a PowerShell session. The XML document that is created will most likely not be recognized by traditional or external XML applications. Let’s take a look.
Suppose you have this simple command:

Get-Service wuauserv -ComputerName chi-dc04,chi-p50,chi-core01

And you want to save the results to an XML file. All you need to do is pipe the command to Export-Clixml and specify the name for your output file, as shown below:

Get-Service wuauserv -ComputerName chi-dc04,chi-p50,chi-core01 |
Export-Clixml -Path c:\work\wu.xml

It is very important that your expression write objects to the pipeline. Anything that uses Write-Host won’t write to the pipeline, which means you can’t serialize it. Don’t include any formatting commands, either. Technically, this will run without error.

Get-Service wuauserv -ComputerName chi-dc04,chi-p50,chi-core01 |
format-table -AutoSize |
Export-Clixml -Path c:\work\wu.xml

But when the time comes to bring the file back to life in PowerShell, you won’t get the results you expect.
Let’s take a quick look at the result:

Export-Clixml result
Export-Clixml result (Image Credit: Jeff Hicks)

This XML is more or less valid, although it is lacking the declaration at the beginning and the tags are not especially intuitive. But that’s fine. This file is designed to be consumed by PowerShell and specifically the Import-Clixml cmdlet, which knows how to “read” this file. But if you were to try and use this file outside of PowerShell, you would most likely encounter problems. I’ll get to the alternative in a moment.
Be sure to take a few minutes to read the full help and examples for Export-Clixml. There is no way to append data to an existing file, but you can prevent overwriting an existing file with the -NoClobber parameter.

Convertto-XML

An alternative cmdlet is ConvertTo-XML.  Like Export-Clixml, you should pipe objects to this cmdlet and avoid including any formatting directives.

Converting to XML
Converting to XML (Image Credit: Jeff Hicks)

The first thing you’ll notice is that I don’t get a file. Instead, by default, I get an XML document because that is what the cmdlet is designed to do. It is converting not exporting. You could modify the XML document if you wanted to or explore it.
Navigating the XML
Navigating the XML (Image Credit: Jeff Hicks)

You can examine individual nodes through the InnerXML property.
Inner XML
Inner XML (Image Credit: Jeff Hicks)

Or like this:
View node properties
View node properties (Image Credit: Jeff Hicks)

When you are ready to save the document to a file, use the Save() method.

$x.Save("c:\work\wu2.xml")

I recommend always using a full path and file name. The resulting file is a truer XML file.

Converted XML
Converted XML (Image Credit: Jeff Hicks)

You can also convert and treat the result as a stream.
Converting to a stream
Converting to a stream (Image Credit: Jeff Hicks)

This will create an array of strings representing different parts of the XML document. You could modify the text as needed and then use Out-File, Set-Content or Add-Content to write the results to a file. This is one way you could append to an existing file.
Finally, you can convert your results to an XML string.

Get-Service wuauserv -ComputerName chi-dc04,chi-p50,chi-core01 |
ConvertTo-Xml -as String

You’ll get the same results as with -Stream, but it will be one long string. Again, you can modify the string and then save the results to a file. Or simply convert and export in one command.

Get-Service wuauserv -ComputerName chi-dc04,chi-p50,chi-core01 |
ConvertTo-Xml -as string | Set-Content -path c:\work\wu3.xml

Converted and saved XML
Converted and saved XML (Image Credit: Jeff Hicks)

The fact that I converted the PowerShell output to a string and then saved the results to a file is irrelevant. When the time comes to bring this data back into PowerShell, this file is no different than any of the others I created.

In the next article, I’ll explain how to bring these files back to life. The other technique I didn’t discuss is creating custom XML from scratch. I’ll also cover in a future article. But for now, I encourage you to take a little time trying out these commands.