Managing INI Files with PowerShell Part 2

In the previous article, Managing INI Files with PowerShell, I demonstrated how you might convert a legacy INI file into something more object-oriented for use in PowerShell. At the end of the article, I showed how you could persist the data to disk using Export-Clixml. The potential issue is that the resulting file can only be used within PowerShell. Here’s what my exported sample.ini looks like.

Our sample XML file. (Image Credit: Jeff Hicks)
Our sample XML file. (Image Credit: Jeff Hicks)

The node names are not very meaningful outside of a PowerShell context. I then thought, perhaps I could use the ConvertTo-XML cmdlet. But this fails with my custom object.

An error with the Convertto-XML cmdlet. (Image Credit: Jeff Hicks)
An error with the Convertto-XML cmdlet. (Image Credit: Jeff Hicks)

And further testing shows that the end result is no different. So if I want to take my INI object and export it to a traditional XML file, I will have to do it myself. Fortunately, it isn’t that difficult in PowerShell. I’m going to create a tool, that will take an INI file and create a traditional XML file just like you would use Export-CSV.

First, I’ll need a path for the finished file.

As I did last time, I’ll need the path to the ini file and strip away comments and blank lines.

Next, I’ll create a new XML document.

From here I could simply begin adding nodes. But I want to create a more complete document, so I’m going to take an extra step to create an XML declaration and add it to the document.

This is going to add the line to the beginning of the document

Now I can begin going through each line of content. Each section heading will be separate node that will be a child of a Sections node.

If a section head is detected, then I’ll create a node for it and append it to the parent node.

When I get to setting lines, again, I can split each line. I’m going to create a node using the setting name, i.e. the text to the left of the equal sign.

The value, will become a text value for the new node, which is then appended to the section.

At the end of the process, I will have an XML document with each section as a node.

I can navigate the XML document like any other object.

To save the XML document to a file, I will use the Save() method. I have found that this works best when I use an explicit filesystem path. Using relative paths doesn’t always save the file where I expect. So I came up with some commands to split apart the export path and resolve the parent component.

This will take a path like .\myini.xml and resolve the folder to C:\Scripts, assuming that is the current directory. All I’m really doing is rebuilding the path.

I could have combined several, if not all of these steps into a single expression, but it would be cumbersome and complicated to read. There’s no penalty in breaking the process down into separate steps.

The end result is a more traditional XML file, I could use anywhere.

I suppose since I have a <Sections> node, each child node could be wrapped up in a <Section> node. Or I probably could have skipped insert <Sections> altogether. Or maybe I should have called it <Configuration> or <INI>. Obviously it is up to you. If you want something different, feel free to modify my function.

I even included support for –WhatIf in [cmdletbinding()], since I’m going to create a file. However, because I am invoking .NET methods, they don’t recognize –WhatIf, so I have to write my own code for handling the situation.

Now you have a few tools for converting or exporting INI files to something a bit more modern. And hopefully you picked up a PowerShell trick or two along the way. Got questions? Throw them in the comments.

Related Topics:

  • PowerShell

    Don't have a login but want to join the conversation? Sign up for a Petri Account