Move Get-IniContent, Out-IniFile, WaitForSuccess
- These scripts are universally useful and should be maintained once
This commit is contained in:
131
core/Get-IniContent.ps1
Normal file
131
core/Get-IniContent.ps1
Normal file
@@ -0,0 +1,131 @@
|
||||
#Requires -Version 2.0
|
||||
|
||||
function Get-IniContent
|
||||
{
|
||||
<#
|
||||
.Synopsis
|
||||
Reads the contents of an INI file into an OrderedDictionary
|
||||
.Description
|
||||
The dictionary can be manipulated the same way a Hashtable can, by
|
||||
adding or removing keys to the various sections.
|
||||
|
||||
By using an OrderedDictionary, the contents of the file can be
|
||||
roundtripped through the Out-IniFile cmdlet.
|
||||
|
||||
Nested INI sections represented like the following are supported:
|
||||
|
||||
[foo]
|
||||
name = value
|
||||
[[bar]]
|
||||
name = value
|
||||
;name = value
|
||||
|
||||
Comment lines prefixed with a ; are returned in the output with a name
|
||||
of {Comment-X} where X is the comment index within the entire INI file
|
||||
|
||||
Comments also have an IsComment property attached to the values, so
|
||||
that Out-IniFile may properly handle them.
|
||||
.Notes
|
||||
Inspiration from Oliver Lipkau <oliver@lipkau.net>
|
||||
http://tinyurl.com/9g4zonn
|
||||
.Inputs
|
||||
String or FileInfo
|
||||
.Outputs
|
||||
Collections.Specialized.OrderedDictionary
|
||||
Keys with a OrderdedDictionary Value are representative of sections
|
||||
|
||||
Sections may be nested to any arbitrary depth
|
||||
.Parameter Path
|
||||
Specifies the path to the input file. Can be a string or FileInfo
|
||||
object
|
||||
.Example
|
||||
$configFile = Get-IniContent .\foo.ini
|
||||
|
||||
Description
|
||||
-----------
|
||||
Parses the foo.ini file contents into an OrderedDictionary for local
|
||||
reading or manipulation
|
||||
.Example
|
||||
$configFile = .\foo.ini | Get-IniContent
|
||||
$configFile.SectionName | Select *
|
||||
|
||||
Description
|
||||
-----------
|
||||
Same as the first example, but using pipeline input.
|
||||
Additionally outputs all values stored in the [SectionName] section of
|
||||
the INI file.
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(ValueFromPipeline=$True, Mandatory=$True)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[ValidateScript({ (Test-Path $_) -and ($_.Extension -eq '.ini') })]
|
||||
[IO.FileInfo]
|
||||
$Path
|
||||
)
|
||||
|
||||
Process
|
||||
{
|
||||
Write-Verbose "[INFO]: Get-IniContent processing file [$Path]"
|
||||
|
||||
# TODO: once Powershell 3 is common, this can be $ini = [ordered]@{}
|
||||
$ini = New-Object Collections.Specialized.OrderedDictionary
|
||||
|
||||
function getCurrentOrEmptySection($section)
|
||||
{
|
||||
if (!$section)
|
||||
{
|
||||
if (!$ini.Keys -contains '')
|
||||
{
|
||||
$ini[''] = New-Object Collections.Specialized.OrderedDictionary
|
||||
}
|
||||
$section = $ini['']
|
||||
}
|
||||
return $section
|
||||
}
|
||||
|
||||
$comments = 0
|
||||
$sections = @($ini)
|
||||
switch -regex -file $Path
|
||||
{
|
||||
#http://stackoverflow.com/questions/9155483/regular-expressions-balancing-group
|
||||
'\[((?:[^\[\]]|(?<BR> \[)|(?<-BR> \]))+(?(BR)(?!)))\]' # Section
|
||||
{
|
||||
$name = $matches[1]
|
||||
# since the regex above is balanced, depth is a simple count
|
||||
$depth = ($_ | Select-String '\[' -All).Matches |
|
||||
Measure-Object |
|
||||
Select -ExpandProperty Count
|
||||
|
||||
# root section
|
||||
Write-Verbose "Parsing section $_ at depth $depth"
|
||||
# handles any level of nested section
|
||||
$section = New-Object Collections.Specialized.OrderedDictionary
|
||||
$sections[$depth - 1][$name] = $section
|
||||
if ($sections.Length -le $depth)
|
||||
{
|
||||
$sections += $section
|
||||
}
|
||||
else
|
||||
{
|
||||
$sections[$depth] = $section
|
||||
}
|
||||
}
|
||||
'^(;.*)$' # Comment
|
||||
{
|
||||
$section = getCurrentOrEmptySection $section
|
||||
$name = '{Comment-' + ($comments++) + '}'
|
||||
$section[$name] = $matches[1] |
|
||||
Add-Member -MemberType NoteProperty -Name IsComment -Value $true -PassThru
|
||||
}
|
||||
'(.+?)\s*=\s*(.*)' # Key
|
||||
{
|
||||
$name, $value = $matches[1..2]
|
||||
(getCurrentOrEmptySection $section)[$name] = $value
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose "[SUCCESS]: Get-IniContent processed file [$path]"
|
||||
return $ini
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user