Private/Read-Properties.ps1
# ------------------------------------------------------------------------------ # Properties parsing function # ------------------------------------------------------------------------------ function Read-Properties { <# .SYNOPSIS Parse properties file .DESCRIPTION Parse properties file to generate configuration variables .PARAMETER Path The patch parameter corresponds to the path to the property file to read. .PARAMETER Section [Switch] The Section parameter indicates if properties should be grouped depending on existing sections in the file. .OUTPUTS [System.Collections.Specialized.OrderedDictionary] Read-Properties returns an ordered hash table containing the content of the property file. .EXAMPLE Read-Properties -Path ".\conf\default.ini" -Section In this example, Read-Properties will parse the default.ini file contained in the .\conf directory and generate an ordered hashtable containing the key-values pairs. #> [CmdletBinding ()] Param ( [Parameter ( Position = 1, Mandatory = $true, HelpMessage = "Path to the property file" )] [ValidateNotNullOrEmpty ()] [String] $Path, [Parameter ( Position = 3, Mandatory = $false, HelpMessage = "Define if section headers should be used to group properties or be ignored" )] [Switch] $Section ) Begin { # Get global preference variables Get-CallerPreference -Cmdlet $PSCmdlet -SessionState $ExecutionContext.SessionState # Instantiate variables $Properties = New-Object -TypeName "System.Collections.Specialized.OrderedDictionary" $Sections = New-Object -TypeName "System.Collections.Specialized.OrderedDictionary" $Header = $null $errors = 0 } Process { # Check that the file exists if (Test-Path -Path $Path) { $ListOfProperties = Get-Content -Path $Path $LineNumber = 0 # Read the property file line by line foreach ($Property in $ListOfProperties) { $LineNumber += 1 # If properties have to be grouped by section if ($Section) { # If end of file and section is open if ($LineNumber -eq $ListOfProperties.Count -And $Header) { if ($Property[0] -ne "#" -And $Property[0] -ne ";" -And $Property -ne "") { $Property = Read-Property -Property $Property if ($Property.Count -gt 0) { $Sections.Add($Property.Key, $Property.Value) } else { Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" } } $Clone = Copy-OrderedHashtable -Hashtable $Sections -Deep $Properties.Add($Header, $Clone) } elseif ($Property[0] -eq "[") { # If previous section exists add it to the property list if ($Header) { $Clone = Copy-OrderedHashtable -Hashtable $Sections -Deep $Properties.Add($Header, $Clone) } # Create new property group $Header = $Property.Substring(1, $Property.Length - 2) $Sections.Clear() } elseif ($Header -And $Property[0] -ne "#" -And $Property[0] -ne ";" -And $Property -ne "") { $Property = Read-Property -Property $Property if ($Property.Count -gt 0) { $Sections.Add($Property.Key, $Property.Value) } else { Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" } } } else { # Ignore comments, sections, and blank lines if ($Property[0] -ne "#" -And $Property[0] -ne ";" -And $Property[0] -ne "[" -And $Property -ne "") { $Property = Read-Property -Property $Property if ($Property.Count -gt 0) { try { $Properties.Add($Property.Key, $Property.Value) } catch { Write-Log -Type "WARN" -Object "Two distinct definitions of the property $($Property.Key) have been found in the configuration file" $Errors += 1 } } else { Write-Log -Type "WARN" -Message "Unable to process line $LineNumber from $Path" } } } } } else { # Alert that configuration file does not exist at specified location Write-Log -Type "ERROR" -Message "Path not found $Path" -ExitCode 1 } if ($Errors -gt 0) { Write-Log -Type "ERROR" -Object "Unable to proceed. Resolve the issues in $Path" -ExitCode 1 } return $Properties } } |