Import-INIToPSObject.ps1
<#PSScriptInfo
.VERSION 0.0.0.1 .GUID 02dc8320-d51a-41c8-ae60-fb8b58e3f28b .AUTHOR Luke Dalton .COPYRIGHT GNU GPL v3 .TAGS INI .LICENSEURI https://www.gnu.org/licenses/gpl-3.0.en.html .PROJECTURI https://psytechnic.blogspot.co.uk .ICONURI .EXTERNALMODULEDEPENDENCIES .REQUIREDSCRIPTS .EXTERNALSCRIPTDEPENDENCIES .RELEASENOTES (c) 25 September 2018 Version History: 0.0.0.1 - First Write .Description Reads lines from .ini files and constructs a custom PSObject which can be modified and exported #> Function Import-INIToPSObject{ [CmdletBinding()] [OutputType([System.Management.Automation.PSCustomObject])] param( # Full path of .ini file to import [Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True)][ValidateNotNullOrEmpty()][ValidateScript({Test-Path -Path $_})][string]$Path, # Interpret lines ending with ' \' as line break [Parameter(Position=1,Mandatory=$False)][switch]$MultiLine, # Ignores inline and full line comments (';') [Parameter(Position=2,Mandatory=$False)][switch]$IgnoreComments, # Force overwrite of duplicate sections or values [Parameter(Position=3,Mandatory=$False)][switch]$Force ) Begin{ $commandName=$MyInvocation.MyCommand.Name Function Process-String([parameter(Mandatory=$True)][string]$string){ $return=$string.Trim() switch -Regex ($return){ '^\".*\"$'{$return=$return-replace'^\"'-replace'\"$';Continue} "^\'.*\'$"{$return=$return-replace"^\'"-replace"\'$";Continue} } $return } } Process{ Write-Verbose -Message "$commandName : Creating new PSCustomObject from INI" $returnObject=New-Object -TypeName PSObject $sectionName=$null Write-Verbose -Message "$commandName : Reading data from -" Write-Verbose -Message "$commandName : $Path" Try{$fileLines=[IO.File]::ReadAllLines($Path)}Catch{$_;Return} Write-Verbose -Message "$commandName : Reading lines" For($index=0;$index-lt$fileLines.Count;$index++){ $fileLine=$fileLines[$index] if($previousLine){$fileLine="$previousLine$fileLine"} if($MultiLine-and$fileLine-match'\s+\\$'){$previousLine=$fileLine-replace'\s+\\$';Continue}else{$previousLine=$null} $lineLabel="Line [$($index+1)\$($fileLines.Count)]: $fileLine" if($sectionName){$toModify=$returnObject."$sectionName"}else{$toModify=$returnObject} switch -Regex ($fileLine){ "^\s*\[(.+)\]"{ if($fileLine.IndexOf(';')-ge0){ if(-not($IgnoreComments)){ $comment=$fileLine.SubString($fileLine.IndexOf(';')+1).Trim() $inlineCommentCount+=1 $commentName="`;InlineComment$inlineCommentCount" $toModify|Add-Member -MemberType NoteProperty -Name $commentName -Value $comment -Force:$Force Write-Verbose -Message "$commandName :`r`n$lineLabel`r`nComment : $commentName = $comment" } } $commentCount=$inlineCommentCount=0 $sectionName=Process-String $Matches[1] try{$returnObject|Add-Member -MemberType NoteProperty -Name $sectionName -Value (New-Object -TypeName PSObject) -Force:$Force -ErrorAction Stop} catch{ $message="`r`n$lineLabel`r`nINI Read Error : $($_.Exception.Message)" switch($ErrorActionPreference){ 'Stop'{Write-Error -Message $message;Return} 'Continue'{Write-Warning -Message "$commandName : $message";Continue} Default{Write-Verbose -Message "$commandName : $message";Continue} } } Write-Verbose -Message "$commandName :`r`n$lineLabel`r`nSection Name : $sectionName" Continue } "^;(.*)$"{ if(-not($IgnoreComments)){ $comment=$Matches[1].Trim() $commentCount+=1 $name="`;Comment$commentCount" $toModify|Add-Member -MemberType NoteProperty -Name $name -Value $comment -Force:$Force Write-Verbose -Message "$commandName :`r`n$lineLabel`r`nComment : $name = $comment" } Continue } "(.+?)\s*=\s*(.*)"{ $name,$value=$Matches[1..2] if($value.IndexOf(';')-ge0){ if(-not($IgnoreComments)){ $comment=$value.SubString($value.IndexOf(';')+1).Trim() $inlineCommentCount+=1 $commentName="`;InlineComment$inlineCommentCount" $toModify|Add-Member -MemberType NoteProperty -Name $commentName -Value $comment -Force:$Force Write-Verbose -Message "$commandName :`r`n$lineLabel`r`nComment : $commentName = $comment" } $value=$value.SubString(0,$value.IndexOf(';')) } $name=Process-String $name $value=Process-String $value Write-Verbose -Message "$commandName :`r`n$lineLabel`r`nProperty : $name = $value" try{$ToModify|Add-Member -MemberType NoteProperty -Name $name -Value $value -Force:$Force -ErrorAction Stop} catch{ $message="`r`n$lineLabel`r`nINI Read Error : $($_.Exception.Message)" switch($ErrorActionPreference){ 'Stop'{Write-Error -Message $message;Return} 'Continue'{Write-Warning -Message "$commandName : $message";Continue} Default{Write-Verbose -Message "$commandName : $message";Continue} } } Continue } "^\s*$"{Write-Verbose -Message "$commandName :`r`n$lineLabel`r`nEmpty Line";Continue} Default{ $message="`r`n$lineLabel`r`nINI Read Error : Unrecognised pattern" switch($ErrorActionPreference){ 'Stop'{Write-Error -Message $message;Return} 'Continue'{Write-Warning -Message "$commandName : $message";Continue} Default{Write-Verbose -Message "$commandName : $message";Continue} } } } } Write-Verbose -Message "$commandName : Returning constructed object" $returnObject } End{} } |