"But I want it that way..."
Why INI?
I've embraced the .NET reliance in PowerShell,
regex handling,
direct member calls and
dot notation. I really like using PowerShell (and worth the price -
ISESteroids) to develop scripts for managing the 800+ computers I maintain. From bulk domain management to full system deployments with faster results than MDT, PowerShell can handle it all. If you're working with deploying applications and creating deployments, handling INI files becomes inevitable and it's worth reading the
fairly simple structure of an INI file being that they are so often used in installers, setup files and others. Other files,
such as INF, take the INI structure further and provide more complex functionality, but there are many old and new technologies still using INIs as configuration files and
some of the Microsoft Windows system files are in INI format.
My Interest in this
Handling files with a text editor is faster when working with one or two files, but if you need to handle hundreds of copies distributed across computers or folders, then this becomes tedious. I'm a huge fan and advocate of
PortableApps.com for having a suite of tools on a USB stick. The folder structure for this comprises of a few INI files and I wanted a quick way to reference this information in a script so I could remove all the games.
There are already ways
In the search to find a Google solution, I discovered
this Microsoft Scripting Guy post that describes how to feed a file, line by line through PowerShell's switch function with the -File parameter and provides links to more complete scripts which, with much respect to Oliver Lipkau, gave me the base idea and regex strings.
Tweak, tweak...
A few things were lacking in the solution that I really wanted to change:
- The returned object is a HashTable
I embrace the PowerShell over .Net so a raw hash table although may be faster than other methods, can be more cumbersome to handle in code with try catch statements and reading the object in the console requires additional discovery before querying values. I also think this looks ugly and doesn't leverage the dot notation or autocomplete of PowerShell.
- The returned values are out of order when exported
The sections and values of the INI are loaded into a HashTable which does not retain structure order when writing back to the file (given the functions supplied). This can be particularly irritating for manual editors who like to keep the order of comments, sections and values.
So I rewrote the PowerShell Functions for a little more flavour.
Results were:
- PowerShell 2.0 support
- Verbose is noisy, SilentlyContinue is quiet
For the Import:
- Accepts path input from pipeline (absolute paths)
- Full Line Comments are noted in a ";Comment#" NoteProperty
- Inline Comments are noted in a ";InlineComment#" NoteProperty preceding the property or section
- Errors and warnings based on $ErrorActionPreference
- The Object returned is a PSCustomObject with dot notation accessible settable properties.
- Quotation translation (" and ') is performed.
- Multi line (line ending in ' \') is supported by switch
For the Export:
- Values, Sections and Comments are to be written back into the file in the same order.
- Confirmation will be shown on attempted overwrite, but not on append, unless forced.
- Encoding option can be selected from default set.
- Switches to enclose the section names, property names and values in quotaion marks
How to use:
Import-INIToPSObject:
$example = Import-INIToPSObject -Path C:\Temp\test.ini
Then let PowerShell do the autocomplete magic:
Listing a section:
Modifying Values:
Export-PSObjectToINI:
$example | Export-PSObjectToINI -Path C:\Temp\test.ini
Sometimes you're modifying, sometimes you're creating files on the fly. If the latter is the case, you can create a new INI Object by defining a structure like this:
[pscustomobject]@{
rootProp1='test1'
rootProp2=$null
section1=[pscustomobject]@{
sectProp1=$true
sectProp2=4
}
section2=[pscustomobject]@{
sectProp1=$false
sectProp2=''
}
}|Export-PSObjectToINI -Path 'C:\temp\test.ini'
Not as pretty but... CODE!
The code is now available on the PowerShell Gallery!