Skip to content

Commit

Permalink
* Separated functions into individual files
Browse files Browse the repository at this point in the history
* Added Unit Tests (not tested yet)
* Small optimizations in code and naming
* cleanup
  • Loading branch information
lipkau committed Jul 14, 2015
1 parent c3addce commit 19a413c
Show file tree
Hide file tree
Showing 10 changed files with 451 additions and 394 deletions.
2 changes: 1 addition & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1 @@
*.psd1 text

126 changes: 126 additions & 0 deletions Functions/Get-IniContent.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
Function Get-IniContent {
<#
.Synopsis
Gets the content of an INI file
.Description
Gets the content of an INI file and returns it as a hashtable
.Notes
Author : Oliver Lipkau <oliver@lipkau.net>
Source : https://github.com/lipkau/PsIni
http://gallery.technet.microsoft.com/scriptcenter/ea40c1ef-c856-434b-b8fb-ebd7a76e8d91
Version : 1.0.0 - 2010/03/12 - OL - Initial release
1.0.1 - 2014/12/11 - OL - Typo (Thx SLDR)
Typo (Thx Dave Stiff)
1.0.2 - 2015/06/06 - OL - Improvment to switch (Thx Tallandtree)
1.0.3 - 2015/06/18 - OL - Migrate to semantic versioning (GitHub issue#4)
1.0.4 - 2015/06/18 - OL - Remove check for .ini extension (GitHub Issue#6)
1.1.0 - 2015/07/14 - CB - Improve round-tripping and be a bit more liberal (GitHub Pull #7)
OL - Small Improvments and cleanup
#Requires -Version 2.0
.Inputs
System.String
.Outputs
System.Collections.Hashtable
.Parameter FilePath
Specifies the path to the input file.
.Parameter HashComments
Treat lines starting with # as a comment.
.Parameter StripComments
Remove lines determined to be comments from the resulting dictionary.
.Example
$FileContent = Get-IniContent "C:\myinifile.ini"
-----------
Description
Saves the content of the c:\myinifile.ini in a hashtable called $FileContent
.Example
$inifilepath | $FileContent = Get-IniContent
-----------
Description
Gets the content of the ini file passed through the pipe into a hashtable called $FileContent
.Example
C:\PS>$FileContent = Get-IniContent "c:\settings.ini"
C:\PS>$FileContent["Section"]["Key"]
-----------
Description
Returns the key "Key" of the section "Section" from the C:\settings.ini file
.Link
Out-IniFile
#>

[CmdletBinding()]
Param(
[ValidateNotNullOrEmpty()]
[ValidateScript({(Test-Path $_)})]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[string]$FilePath,
[char[]]$CommentChar = @(";"),
[switch]$StripComments
)

Begin
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started"
$commentRegex = "^([$($CommentChar -join '')].*)$"
}

Process
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Processing file: $Filepath"

$ini = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase)
switch -regex -file $FilePath
{
"^\[(.+)\]$" # Section
{
$section = $matches[1]
$ini[$section] = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase)
$CommentCount = 0
continue
}
$commentRegex # Comment
{
if (!$StripComments)
{
if (!($section))
{
$section = "_"
$ini[$section] = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase)
}
$value = $matches[1]
$CommentCount++
$name = "Comment" + $CommentCount
$ini[$section][$name] = $value
}
continue
}
"(.+?)\s*=\s*(.*)" # Key
{
if (!($section))
{
$section = "_"
$ini[$section] = New-Object System.Collections.Specialized.OrderedDictionary([System.StringComparer]::OrdinalIgnoreCase)
}
$name,$value = $matches[1..2]
$ini[$section][$name] = $value
continue
}
}
Write-Verbose "$($MyInvocation.MyCommand.Name):: Finished Processing file: $FilePath"
Return $ini
}

End
{Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"}
}
220 changes: 220 additions & 0 deletions Functions/Out-IniFile.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
Function Out-IniFile {
<#
.Synopsis
Write hash content to INI file
.Description
Write hash content to INI file
.Notes
Author : Oliver Lipkau <oliver@lipkau.net>
Blog : http://oliver.lipkau.net/blog/
Source : https://github.com/lipkau/PsIni
http://gallery.technet.microsoft.com/scriptcenter/ea40c1ef-c856-434b-b8fb-ebd7a76e8d91
Version : 1.0.0 - 2010/03/12 - OL - Initial release
1.0.1 - 2012/04/19 - OL - Bugfix/Added example to help (Thx Ingmar Verheij)
1.0.2 - 2014/12/11 - OL - Improved handling for missing output file (Thx SLDR)
1.0.3 - 2014/01/06 - CB - removed extra \r\n at end of file
1.0.4 - 2015/06/06 - OL - Typo (Thx Dominik)
1.0.5 - 2015/06/18 - OL - Migrate to semantic versioning (GitHub issue#4)
1.0.6 - 2015/06/18 - OL - Remove check for .ini extension (GitHub Issue#6)
1.1.0 - 2015/07/14 - CB - Improve round-tripping and be a bit more liberal (GitHub Pull #7)
OL - Small Improvments and cleanup
#Requires -Version 2.0
.Inputs
System.String
System.Collections.IDictionary
.Outputs
System.IO.FileSystemInfo
.Parameter Append
Adds the output to the end of an existing file, instead of replacing the file contents.
.Parameter InputObject
Specifies the Hashtable to be written to the file. Enter a variable that contains the objects or type a command or expression that gets the objects.
.Parameter FilePath
Specifies the path to the output file.
.Parameter Encoding
Specifies the file encoding. The default is UTF8.
Valid values are:
-- ASCII: Uses the encoding for the ASCII (7-bit) character set.
-- BigEndianUnicode: Encodes in UTF-16 format using the big-endian byte order.
-- Byte: Encodes a set of characters into a sequence of bytes.
-- String: Uses the encoding type for a string.
-- Unicode: Encodes in UTF-16 format using the little-endian byte order.
-- UTF7: Encodes in UTF-7 format.
-- UTF8: Encodes in UTF-8 format.
.Parameter Force
Allows the cmdlet to overwrite an existing read-only file. Even using the Force parameter, the cmdlet cannot override security restrictions.
.Parameter PassThru
Passes an object representing the location to the pipeline. By default, this cmdlet does not generate any output.
.Parameter Loose
Adds spaces around the equal sign when writing the key = value
.Example
Out-IniFile $IniVar "C:\myinifile.ini"
-----------
Description
Saves the content of the $IniVar Hashtable to the INI File c:\myinifile.ini
.Example
$IniVar | Out-IniFile "C:\myinifile.ini" -Force
-----------
Description
Saves the content of the $IniVar Hashtable to the INI File c:\myinifile.ini and overwrites the file if it is already present
.Example
$file = Out-IniFile $IniVar "C:\myinifile.ini" -PassThru
-----------
Description
Saves the content of the $IniVar Hashtable to the INI File c:\myinifile.ini and saves the file into $file
.Example
$Category1 = @{“Key1”=”Value1”;”Key2”=”Value2”}
$Category2 = @{“Key1”=”Value1”;”Key2”=”Value2”}
$NewINIContent = @{“Category1”=$Category1;”Category2”=$Category2}
Out-IniFile -InputObject $NewINIContent -FilePath "C:\MyNewFile.ini"
-----------
Description
Creating a custom Hashtable and saving it to C:\MyNewFile.ini
.Link
Get-IniContent
#>

[CmdletBinding()]
Param(
[switch]$Append,

[ValidateSet("Unicode","UTF7","UTF8","ASCII","BigEndianUnicode","Byte","String")]
[Parameter()]
[string]$Encoding = "UTF8",

[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_ -IsValid})]
[Parameter(Mandatory=$True,
Position=0)]
[string]$FilePath,

[switch]$Force,

[ValidateNotNullOrEmpty()]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[System.Collections.IDictionary]$InputObject,

[switch]$Passthru,

[switch]$Loose
)

Begin
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Function started"

function Out-Keys
{
param(
[ValidateNotNullOrEmpty()]
[Parameter(ValueFromPipeline=$True,Mandatory=$True)]
[System.Collections.IDictionary]$InputObject,

[ValidateSet("Unicode","UTF7","UTF8","ASCII","BigEndianUnicode","Byte","String")]
[Parameter(Mandatory=$True)]
[string]$Encoding = "UTF8",

[ValidateNotNullOrEmpty()]
[ValidateScript({Test-Path $_ -IsValid})]
[Parameter(Mandatory=$True,
ValueFromPipelineByPropertyName=$true)]
[string]$Path,

[Parameter(Mandatory=$True)]
$delimiter,

[Parameter(Mandatory=$True)]
$MyInvocation
)

Process
{
Foreach ($key in $InputObject.keys)
{
if ($key -match "^Comment\d+") {
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing comment: $key"
Add-Content -Value "$($InputObject[$key])" @parameters
} else {
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing key: $key"
Add-Content -Value "$key$delimiter$($InputObject[$key])" @parameters
}
}
}
}

$delimiter = '='
if ($Loose)
{ $delimiter = ' = ' }

if ($append)
{$outfile = Get-Item $FilePath}
else
{$outFile = New-Item -ItemType file -Path $Filepath -Force:$Force}

if (!(Test-Path $outFile.FullName)) {Throw "Could not create File"}

#Splatting Parameters
$parameters = @{
Encoding = $Encoding;
Path = $FilePath
}

}

Process
{
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing to file: $Filepath"
foreach ($i in $InputObject.keys)
{
if (!($InputObject[$i].GetType().GetInterface('IDictionary')))
{
#No Sections
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing key: $i"
Add-Content -Value "$i$equal$($InputObject[$i])" `
@parameters

} elseif ($i -eq '_') {
Out-Keys $InputObject[$i] ` @parameters `
-delimiter $delimiter `
-MyInvocation $MyInvocation
} else {
#Sections
Write-Verbose "$($MyInvocation.MyCommand.Name):: Writing Section: [$i]"
Add-Content -Value "[$i]" `
@parameters
Out-Keys $InputObject[$i] `
@parameters `
-delimiter $delimiter `
-MyInvocation $MyInvocation

Add-Content -Value "" `
@parameters
}
}
Write-Verbose "$($MyInvocation.MyCommand.Name):: Finished Writing to file: $FilePath"
}

End
{
if ($PassThru)
{ Return (Get-Item $outFile) }
Write-Verbose "$($MyInvocation.MyCommand.Name):: Function ended"
}
}
Expand Down
Loading

0 comments on commit 19a413c

Please sign in to comment.