Private/Get-IniContent.ps1
function Get-IniContent { <# .SYNOPSIS Gets the content of an INI file and returns it as a hashtable. .DESCRIPTION Parses an INI file and returns a nested hashtable of its contents. Supports sections, keys, values, and comments. Handles files with or without sections. .PARAMETER FilePath Specifies the path to the input INI file. Accepts pipeline input. Must be a valid file path. .INPUTS [System.String] You can pipe a file path to this function. .OUTPUTS [System.Collections.Hashtable] Returns a hashtable containing the sections, keys, and values from the INI file. .EXAMPLE Get-IniContent -FilePath "C:\Config\settings.ini" Returns the content of settings.ini as a nested hashtable. .EXAMPLE "C:\Config\app.ini" | Get-IniContent Reads app.ini via pipeline and returns its content. .EXAMPLE $config = Get-IniContent "C:\Config\settings.ini" $value = $config["Section"]["Key"] Gets a specific value from the INI structure. .NOTES Used Functions: Name ║ Module/Namespace ═══════════════════════════════════════╬══════════════════════════════ Write-Verbose ║ Microsoft.PowerShell.Utility Write-Debug ║ Microsoft.PowerShell.Utility Write-Error ║ Microsoft.PowerShell.Utility Get-FunctionDisplay ║ EguibarIT .NOTES Version: 2.1 DateModified: 22/May/2025 LastModifiedBy: Vicente Rodriguez Eguibar vicente@eguibar.com Eguibar IT http://www.eguibarit.com .LINK https://github.com/vreguibar/EguibarIT/blob/main/Private/Get-IniContent.ps1 .COMPONENT Configuration Management .ROLE File Parsing .FUNCTIONALITY INI File Processing #> [CmdletBinding( SupportsShouldProcess = $false, ConfirmImpact = 'Low' )] [OutputType([System.Collections.Hashtable])] Param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'Path to the INI file to be parsed')] [ValidateNotNullOrEmpty()] [ValidateScript({ if (-not (Test-Path -Path $_ -PathType Leaf)) { throw "File not found: $_" } #end if return $true })] [Alias('Path', 'ConfigFile')] [string] $FilePath ) Begin { Set-StrictMode -Version Latest # Output header information if ($null -ne $Variables -and $null -ne $Variables.Header) { $txt = ($Variables.Header -f (Get-Date).ToString('dd/MMM/yyyy'), $MyInvocation.Mycommand, (Get-FunctionDisplay -HashTable $PsBoundParameters -Verbose:$False) ) Write-Verbose -Message $txt } #end if ############################## # Variables Definition $script:ini = [ordered]@{} $script:currentSection = $null $script:commentCount = 0 } #end Begin Process { Try { $ini = @{} switch -regex -file $PSBoundParameters['FilePath'] { # Section '^\[(.+)\]$' { $script:currentSection = $matches[1].Trim() $script:ini[$currentSection] = [ordered]@{} $script:commentCount = 0 Write-Debug -Message ('Found section: {0}' -f $currentSection) continue } #end Section # Comment '^;(.*)$' { if ($null -eq $script:currentSection) { $script:currentSection = 'NoSection' $script:ini[$currentSection] = [ordered]@{} } $script:commentCount++ $script:ini[$currentSection]["Comment$commentCount"] = $matches[1].Trim() Write-Debug -Message ('Found comment: {0}' -f $matches[1]) continue } #end Comment # Key-Value Pair '(.+?)\s*=\s*(.*)' { if ($null -eq $script:currentSection) { $script:currentSection = 'NoSection' $script:ini[$currentSection] = [ordered]@{} } $key = $matches[1].Trim() $value = $matches[2].Trim() $script:ini[$currentSection][$key] = $value Write-Debug -Message ('Found key-value: {0} = {1}' -f $key, $value) continue } #end Key-Value Pair } #end switch } catch { Write-Error -Message "An error occurred while processing the file: $_" throw } #end Try-Catch } # End Process End { # Display function footer if ($null -ne $Variables -and $null -ne $Variables.Footer) { $txt = ($Variables.Footer -f $MyInvocation.InvocationName, ('reading content from {0} file (Private Function).' -f $PSBoundParameters['FilePath']) ) Write-Verbose -Message $txt } #end if # Return the populated hashtable return $script:ini } #end End } #end Function Get-IniContent |