Lately, I have been finding that it can be really useful to read the contents of an INI file into PowerShell. Not only does Windows and some applications store some of its configuration data in INI files, but you can also use this technique to build PowerShell scripts that behave differently based on the configuration data stored in an external INI file. For example, an INI file might store the localization to be used by a script, or the script’s color scheme, or just about anything else you can imagine.
Reading an INI file into PowerShell is simple. You can do it with a single line of code. Here is an example:
$INI = Get-Content C:\Scripts\Example.ini
In this case, I am writing the contents of the INI file to a variable named $INI. If I output the variable’s contents, you can see what the INI file contains, as shown in the figure below.
Placing INI files values into PowerShell hash table
Of course, there is a big difference between reading an INI file’s contents into a variable and putting the INI file’s contents into a usable format. For this article, I will show you how to place each of the values found within the INI file into a hash table. If you are not familiar with hash tables, then be sure to check out my recent article on the subject.
Unfortunately, there isn’t an automated function for converting an INI file’s contents into a PowerShell hash table. As you can imagine, the process tends to be a little bit convoluted. Even so, I will make this as painless as I can.
In addition to the hash table that we are creating, we will need to make use of two arrays that will temporarily hold the data until we can place it into the hash table. I will define one of those arrays ($IniTemp) at the beginning of the script, along with the hash table ($IniHash). I will be creating the other array ($SplitArray) dynamically later on in the script.
As previously mentioned, the first step in creating a hash table based on the contents of an INI file is to read the file into PowerShell. Since the ultimate goal is to create a hash table, however, we are going to have to do a bit more work than just using the Get-Content cmdlet.
If you look back at the previous screen capture, you will notice that an INI file typically consists of more than just key/value pairs. There are also section headers (enclosed in brackets) and blank lines. Before we can even think about adding the data from an INI file to a hash table, we have to filter out the blank lines and section headers. This is where the first array ($IniTemp) comes into play.
PowerShell makes it possible to read a text file (in this case, an INI file) line by line. After we read a line, we can perform a couple of simple tests to see if the line is blank or if it starts with a bracket (which would indicate that it is a header line). If the line is blank or if it starts with a bracket, then we will just ignore the line. However, if the line is not blank and does not start with a bracket, we will add it to the array. The result should be that the $IniTemp array contains only the data placed into the hash table. It should not contain any header rows or blank lines. Here is the code that I am using:
Write-Host ('This is the raw INI file contents: ') Write-Host $INI = Get-Content C:\Scripts\Example.ini $Ini $IniHash = @{} $IniTemp = @() ForEach($Line in $INI) { If ($Line -ne "" -and $Line.StartsWith("[") -ne $True) { $IniTemp += $Line } } Write-Host Write-Host('=============================================') Write-Host Write-Host ('This is what has been added to $IniTemp after filtering') Write-Host $IniTemp
This block of code is actually longer than it needs to be. I added several Write-Host statements that help to illustrate what is going on as the code runs. As previously noted, the script starts by reading the INI file, creating an empty hash table, and creating an empty array. The filtering process is accomplished with the ForEach loop. This loop goes through the script one line at a time and checks to see if the line is a blank row or a header row. If the line contains actual data, meaning that it isn’t blank and is not a header row, it is added to the $IniTemp array. You can see the actual code and its output in the next figure.
Converting the array data into a hash table
Now that we have filtered the data and placed it into an array, the last step is to convert the array data into a hash table. This is where things get a little bit tricky. A hash table consists of key/value pairs, but right now, our array only contains text strings. The key to converting the array contents into a hash table is to split each line at the equal sign. This is where the dynamically created array that I mentioned earlier will come into play. Everything to the left of the equal sign will go into position 0 of this dynamically created array (which is called $SplitArray). Everything to the right of the equal sign goes into array position 1. Once that happens, we can add the $SplitArray contents to the hash table, with array position 0 acting as the key and array position 1 acting as the value. Here is the code:
ForEach($Line in $IniTemp) { $SplitArray = $Line.Split("=") $IniHash += @{$SplitArray[0] = $SplitArray[1]} }
As you can see, I have created another ForEach loop. This one processes each line of the $IniTemp array one at a time. The next line of code splits the text string within the array at the equal sign, and the line beneath it adds the split values to the hash table. Here is what the full script looks like:
Write-Host ('This is the raw INI file contents: ') Write-Host $INI = Get-Content C:\Scripts\Example.ini $Ini $IniHash = @{} $IniTemp = @() ForEach($Line in $INI) { If ($Line -ne "" -and $Line.StartsWith("[") -ne $True) { $IniTemp += $Line } } Write-Host Write-Host('=============================================') Write-Host Write-Host ('This is what has been added to $IniTemp after filtering') Write-Host $IniTemp Write-Host Write-Host('===============================================') Write-Host Write-Host('Here is the hash table:') Write-Host ForEach($Line in $IniTemp) { $SplitArray = $Line.Split("=") $IniHash += @{$SplitArray[0] = $SplitArray[1]} } $IniHash
You can see the actual script and its output in the next figure.
Avoiding complex string manipulations
So that’s how you can read the contents of an INI file into a hash table. There are more concise ways of doing this, but I used this particular approach because it avoids a lot of the more complex string manipulations.
Featured image: Shutterstock / TechGenix photo illustration
The post Reading a Windows INI file into PowerShell appeared first on TechGenix.