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.
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.
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.
<# .Synopsis Export a traditional INI file to XML .Description This command will convert a traditional INI file to XML and save to a file. Blank lines and comments starting with ; will be ignored. An ini file like this: ;This is a sample ini [General] Action = Start Directory = c:\work ID = 123ABC ;this is another comment [Application] Name = foo.exe Version = 1.0 [User] Name = Jeff Company = Globomantics Will be exported to an XML file like this: <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Sections> <General> <Action>Start</Action> <Directory>c:\work</Directory> <ID>123ABC</ID> </General> <Application> <Name>foo.exe</Name> <Version>1.0</Version> </Application> <User> <Name>Jeff</Name> <Company>Globomantics</Company> </User> </Sections> IMPORTANT: Due to the nature of XML especially in regard to limitations in naming nodes, some ini settings might not be "exportable" to this format. .Parameter Path The filename and path to the INI file. .Parameter ExportPath The filename and path for the saved XML file. .Example PS C:\> export-initoxml c:\scripts\sample.ini c:\scripts\sample.xml .Notes Last Updated: June 5, 2015 Version : 1.0 Learn more about PowerShell:
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.