8
0

558 lines
44 KiB
PowerShell
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Function Read-ConfigFile {
<#
.SYNOPSIS
Function will read the given ConfigFile, and returns Values or creates Profiles.
.DESCRIPTION
This Function will get Script configurations from a ASCII/ANSI based ConfigFile (INI).
The important criterion is, that every Value the should be read, has to look like this: ConfigLabel = ConfigValue
The ConfigFile should be formated within UTF8 and every Line in a ConfigFile which is beginning with a "#", will be ignored!
By calling this Function the first time, it will read the ConfigFile and save its content into the Variable ConfigFileValues.
In the same call or later calls you can instruct this Function to Return a value for a searched pattern (ConfigLabel).
If nothing was found, Function will try to get a FailSafe Setting (predefined global Variable in Script), if even this fails it will Return $NULL.
Depending on the way your calling this Function, it can return a single Value for a searched ConfigLabel like: $LogPath = E:\Logs,
or it can return multiple Values like; $Domains = .*@my-domain.com;'.*@my-second-domain.com',
or it can create multiple Profiles with single or multiple Values and only returning the Count of the created Profiles.
These cominations are possible and tested:
- Call for 1Line with 1Value - - Call for 1Line with nValues - - Call for nLines with 1Value - - Call for nLines with nValues -
Return -> 0Line - 0Value Return -> 0Line - 0Value Return -> 0Line - 0Value Return -> 0Line - 0Value
Return -> 1Line - 0Value Return -> 1Line - 0Value Return -> 1Line - 0Value Return -> 1Line - 0Value
Return -> 1Line - 1Value Return -> 1Line - 1Value Return -> 1Line - 1Value Return -> 1Line - 1Value
Return -> 1Line - nValues Return -> 1Line - nValues Return -> 1Line - nValues Return -> 1Line - nValues
Return -> nLine - 0Value Return -> nLine - 0Value
Return -> nLine - 1Value Return -> nLine - 1Value
Return -> nLine - nValues Return -> nLine - nValues
.REQUIREMENT General
PowerShell V3
.REQUIREMENT Assembly
<NONE>
.REQUIREMENT Variables
ConfigFile, ConfigLabel, ConfigValue, ConfigValues, ConfigLinesValue, ConfigLinesValueSeparator, FileTest, Item, Items, ItemValue, ItemValues, ItemValuesTEMP
.REQUIREMENT Variables preSet
ConfigFile
.REQUIREMENT Functions
<NONE>
.VERSION
Number: 3.1.0.1 / Date: 08.03.2018
.PARAMETER ConfigFile
Give the full path to the ConfigFile (eg. <ScriptName>_Settings.ini). (Default: If you dont give it, Function will try the retrieve ConfigFile (Path and Name) from the Global Variables, set by the calling Script.)
.PARAMETER ConfigLabel
Give the ConfigLabel, you are looking for a Value.
.PARAMETER ConfigLinesValue
Optional Parameter. Select "MultiValue", if in one Line are multiple Values (eg. Array List) separated by "$ConfigLinesValueSeparator". (Default: "SingleValue").
.PARAMETER ConfigLinesValueSeparator
Optional Parameter. Which declares the symbol or character for Value separation (Default: ';').
.PARAMETER ConfigLines
Optional Parameter. Select how many Lines from ConfigFile you expect to get returned. Use Values higher than 1, to work with Profiles. If you do, Function will set Variables and just returns how many are created! (Default: 1).
.PARAMETER Force
Optional Parameter. By using the Force Parameter, ConfigFile will be reloaded.
.EXAMPLE
Set-Variable -Scope Global -Name LogPaths -Value (Read-ConfigFile -ConfigFile "<Path>\<ScriptName>_Settings.ini" -ConfigLabel LogPath) -Force
.EXAMPLE
Set-Variable -Scope Global -Name ListofValues -Value (Read-ConfigFile -ConfigLabel ListofValues -ConfigLinesValue MultiValue) -Force
.EXAMPLE
Set-Variable -Scope Global -Name ProfileCount -Value (Read-ConfigFile -ConfigLabel Profile -ConfigLines 999) -Force
.EXAMPLE
Set-Variable -Scope Global -Name ProfileCount -Value (Read-ConfigFile -ConfigLabel Profile -ConfigLines 999 -ConfigLinesValue MultiValue) -Force
.EXAMPLE
Set-Variable -Scope Global -Name ProfileCount -Value (Read-ConfigFile -ConfigLabel Profile -ConfigLines 999 -ConfigLinesValue MultiValue -ConfigLinesValueSeparator |) -Force
#>
Param (
[Parameter(Position=0,Mandatory=$False,HelpMessage='Give the full path to the ConfigFile (eg. <ScriptName>_Settings.ini). (Default: If you dont give it, Function will try the retrieve ConfigFile (Path and Name) from the Global Variables, set by the calling Script.)')]
[ValidateNotNullOrEmpty()]
[String]$ConfigFile=(Get-Variable -Name ConfigFile -Scope Global -ValueOnly),
[Parameter(Position=1,Mandatory=$False,HelpMessage='Give the ConfigLabel, you are looking for a Value.')]
[ValidateNotNullOrEmpty()]
[String]$ConfigLabel=$NULL,
[Parameter(Position=2,Mandatory=$False,HelpMessage='Optional Parameter. Select "MultiValue", if in one Line are multiple Values (eg. Array List) separated by "$ConfigLinesValueSeparator". (Default: "SingleValue").')]
[ValidateSet("SingleValue","MultiValue")]
[String]$ConfigLinesValue="SingleValue",
[Parameter(Position=3,Mandatory=$False,HelpMessage='Optional Parameter. Which declares the symbol or character for Value separation (Default: ";").')]
[ValidateNotNullOrEmpty()]
[String]$ConfigLinesValueSeparator=';',
[Parameter(Position=4,Mandatory=$False,HelpMessage='Optional Parameter. Select how many Lines from ConfigFile you expect to get returned. Use Values higher than 1, to work with Profiles. If you do, Function will set Variables and just returns how many are created! (Default: 1).')]
[ValidateRange(1,1000)]
[Int]$ConfigLines=1,
[Parameter(Position=5,Mandatory=$False,HelpMessage='Optional Parameter. By using the Force Parameter, ConfigFile will be reloaded.')]
[Switch]$Force
) #end param
Begin {
#Clear Error Variable
$error.clear()
#If ConfigFile wasnt read, do this at first
IF ((($ConfigFile) -and (!$ConfigValues)) -or ($Force -eq $True)) {
Write-Host ""
Write-Host "DEBUG Info - Read-ConfigFile: ConfigFile has not been evaluated jet..."
Write-Host "DEBUG Info - Read-ConfigFile: Checking for ConfigFile: $ConfigFile"
$FileTest = Test-Path -PathType Leaf $ConfigFile
IF ($FileTest -eq $True) {
Write-Host "DEBUG Info - Read-ConfigFile: ConfigFile does exists!"
Try {
Write-Host "DEBUG Info - Read-ConfigFile: Getting Values from ConfigFile."
Set-Variable -Scope Global -Name ConfigValues -Value (Select-String -Path $ConfigFile -pattern "=" | where {-not($_-match ":[0-9]{1,}:#")})
} #end try
Catch {
Write-Host "DEBUG Info - Read-ConfigFile: Cannot get Values from ConfigFile."
Write-Host "DEBUG Info - Read-ConfigFile: Unexpected Error!"
Write-Host $Error
EXIT
} #end catch
Finally {
IF (!$ConfigValues) {
Write-Host "DEBUG Info - Read-ConfigFile: Found no valid Values in ConfigFile!"
Write-Host "DEBUG Info - Read-ConfigFile: Unexpected Error!"
Write-Host $Error
EXIT
} #end if
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: Found"$ConfigValues.count"Lines in ConfigFile!."
Write-Host "DEBUG Info - Read-ConfigFile: These are:"
FOREACH ($ConfigValue in $ConfigValues) {
Write-Host "DEBUG Info - Read-ConfigFile: $($ConfigValue)"
}# end foreach
} #end else
} #end finally
} #end if
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: ConfigFile does not exists!"
Write-Host "DEBUG Info - Read-ConfigFile: Unexpected Error!"
Write-Host $Error
EXIT
} #end else
} #end if
} #end begin
Process {
#If ConfigFile was read
IF (($ConfigFile) -and ($ConfigValues)) {
Write-Host ""
Write-Host "DEBUG Info - Read-ConfigFile: ConfigFile has been evaluated."
Write-Host "DEBUG Info - Read-ConfigFile: You are looking for: $ConfigLabel."
[Array]$Items = $NULL
[Array]$Items = ($ConfigValues.line | Select-String -pattern "$ConfigLabel" | Select-Object -First $ConfigLines)
Write-Host "DEBUG Info - Read-ConfigFile: Line(s) in ConfigFile -> $Items"
#You are looking for one Line in ConfigFile
IF ($ConfigLines -eq 1) {
Write-Host "DEBUG Info - Read-ConfigFile: You are looking for only one Line!"
#If no Line was found, while you looking for one!
IF ($($Items.count) -lt 1) {
Try {
$Items = (Get-Variable -Name $ConfigLabel -ValueOnly -Scope Global -ErrorAction Stop)
IF ($Items) {
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning: $Items"
Return $Items
} #end if
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning nothing."
Return $NULL
} #end else
} #end try
Catch {
Write-Host "DEBUG Info - Read-ConfigFile: Error reading ConfigValue!"
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning nothing."
Return $NULL
} #end catch
} #end if
#If exactly one Line was found, while you looking for one!
ELSEIF (($($Items.count) -eq 1) -or ($($Items.count) -gt 1)) {
Write-Host "DEBUG Info - Read-ConfigFile: Found exactly one Line!"
[Array]$Item = $Items
[Array]$Item = ($Item -split "=",2)
[String]$ItemName = $Item[0]
[String]$ItemName = ($ItemName.TrimStart())
[String]$ItemName = ($ItemName.TrimEnd())
[String]$ItemValues = $Item[1]
[String]$ItemValues = ($ItemValues.TrimStart())
[String]$ItemValues = ($ItemValues.TrimEnd())
#If exactly one Line was found, but has no Value inside!
IF (!$ItemValues) {
Write-Host "DEBUG Info - Read-ConfigFile: ($ConfigLabel) seems to exist, but is not configured jet."
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe Setting will be used, if was configured!"
Try {
$ItemValues = (Get-Variable -Name $ConfigLabel -ValueOnly -Scope Global -ErrorAction Stop)
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning: $ItemValues"
} #end try
Catch {
Write-Host "DEBUG Info - Read-ConfigFile: Error reading ConfigValue!"
} #end catch
} #end if
#Check again after looking for FailSafe Settings...
IF (!$ItemValues) {
Write-Host "DEBUG Info - Read-ConfigFile: Returning NULL, because nothing was found!"
Return $NULL
} #end if
ELSE {
IF ($ConfigLinesValue -eq "SingleValue") {
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Write-Host "DEBUG Info - Read-ConfigFile: Looking for SingleValue Lines."
Write-Host "DEBUG Info - Read-ConfigFile: Value -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: Returning Datatyp: String"
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Return [String]$ItemValues
} #end if
ELSEIF ($ConfigLinesValue -eq "MultiValue") { $ConfigLines
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Write-Host "DEBUG Info - Read-ConfigFile: Looking for MultiValue Lines,"
Write-Host "DEBUG Info - Read-ConfigFile: which are separated by a: $ConfigLinesValueSeparator"
#Prepare Arrays
[Array]$ItemValues = $ItemValues -split "$ConfigLinesValueSeparator"
[System.Collections.ArrayList]$ItemValuesTEMP = @()
#Rebuild the Array, to remove possible Blanks
FOREACH ($ItemValue in $ItemValues) {
IF ($ItemValue) {
#The "| Out-Null" is VERY important, otherwise the Array will be f**ked!
$ItemValue = ($ItemValue.TrimStart())
$ItemValue = ($ItemValue.TrimEnd())
$ItemValuesTEMP.Add("$ItemValue") | Out-null
} #end if
} #end foreach
[Array]$ItemValues = $NULL
[Array]$ItemValues = $ItemValuesTEMP
IF ($($ItemValues.count) -eq 1) {
Write-Host "DEBUG Info - Read-ConfigFile: Found $($ItemValues.count) Array Item!"
Write-Host "DEBUG Info - Read-ConfigFile: Value -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: Returning Datatyp: String"
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Return [String]$ItemValues
} #end if
ELSEIF ($($ItemValues.count) -gt 1) {
Write-Host "DEBUG Info - Read-ConfigFile: Found $($ItemValues.count) Array Items!"
Write-Host "DEBUG Info - Read-ConfigFile: Values -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: Returning Datatyp: Array"
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Return [Array]$ItemValues
} #end elseif
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: Found $($ItemValues.count) Array Item(s)!"
Write-Host "DEBUG Info - Read-ConfigFile: Value(s) -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: Returning Datatyp: $($ItemValues.gettype())"
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Return $ItemValues
} #end else
} #end elseif
} #end else
} #end elseif
#That shouldnt be happen...
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: Error reading ConfigValues!"
Write-Host "DEBUG Info - Read-ConfigFile: Exiting, because of this Issue."
Write-Host $Error
EXIT
} #end else
} #end if
#You are looking for multiple Lines in ConfigFile
ELSEIF ($ConfigLines -gt 1) {
Write-Host "DEBUG Info - Read-ConfigFile: You are looking for multiple Lines!"
#If no Line was found, while you looking for one!
IF ($($Items.count) -lt 1) {
Try {
$Items = (Get-Variable -Name $ConfigLabel -ValueOnly -Scope Global -ErrorAction Stop)
IF ($Items) {
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning: $Items"
Return $Items
} #end if
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning nothing."
Return $NULL
} #end else
} #end try
Catch {
Write-Host "DEBUG Info - Read-ConfigFile: Error reading ConfigValue!"
Write-Host "DEBUG Info - Read-ConfigFile: FailSafe returning nothing."
Return $NULL
} #end catch
} #end if
#If multiple Lines are found, while you looking for one!
ELSEIF (($($Items.count) -eq 1) -or ($($Items.count) -gt 1)) {
Write-Host "DEBUG Info - Read-ConfigFile: Found multiple ($($Items.count)) Lines!"
[Int]$Counter1 = 0
IF (!(Get-Variable Profiles -ErrorAction SilentlyContinue)) {
#Prepare orderd Hashtable for Profiles via .NET Methode
$Global:Profiles = [ordered]@{}
} #end if
FOREACH ($Item in $Items) {
[Array]$Item = ($Item -split "=",2)
[String]$ItemName = $Item[0]
[String]$ItemName = ($ItemName.TrimStart())
[String]$ItemName = ($ItemName.TrimEnd())
[String]$ItemValues = $Item[1]
[String]$ItemValues = ($ItemValues.TrimStart())
[String]$ItemValues = ($ItemValues.TrimEnd())
IF (($ItemName) -and ($ItemValues)) {
[Int]$Counter1 = 0 | Out-Null
DO {
[Int]$Counter1++ | Out-Null
} #end do
UNTIL (!(Get-Variable -Name ($ItemName+$Counter1) -ErrorAction SilentlyContinue))
Write-Host ""
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Write-Host "DEBUG Info - Read-ConfigFile: New Variable eg. Hashtable Key will be:"
Write-Host "DEBUG Info - Read-ConfigFile: Name -> $($ItemName+$Counter1)"
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
IF ($ConfigLinesValue -eq "SingleValue") {
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Write-Host "DEBUG Info - Read-ConfigFile: Looking for SingleValue Lines."
Write-Host "DEBUG Info - Read-ConfigFile: -> $ItemValues"
} #end if
ELSEIF ($ConfigLinesValue -eq "MultiValue") {
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
Write-Host "DEBUG Info - Read-ConfigFile: Looking for MultiValue Lines,"
Write-Host "DEBUG Info - Read-ConfigFile: which are separated by a: $ConfigLinesValueSeparator"
#Rebuild the Array, to remove possible Blanks
[Array]$ItemValues = $ItemValues -split "$ConfigLinesValueSeparator"
[System.Collections.ArrayList]$ItemValuesTEMP = @()
FOREACH ($ItemValue in $ItemValues) {
IF ($ItemValue) {
#The "| Out-Null" is VERY important, otherwise the Array will be f**ked!
$ItemValue = ($ItemValue.TrimStart())
$ItemValue = ($ItemValue.TrimEnd())
$ItemValuesTEMP.Add("$ItemValue") | Out-null
} #end if
} #end foreach
[Array]$ItemValues = $NULL
[Array]$ItemValues = $ItemValuesTEMP
} #end elseif
IF ($($ItemValues.count) -eq 1) {
Write-Host "DEBUG Info - Read-ConfigFile: Found $($ItemValues.count) Array Item!"
Write-Host "DEBUG Info - Read-ConfigFile: Setting Variable: $($ItemName+$Counter1)"
Write-Host "DEBUG Info - Read-ConfigFile: with Value -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: in Datatyp: String"
Set-Variable -Name ($ItemName+$Counter1) -Value ([String]$ItemValues) -Scope Global
$Profiles.Add($ItemName+$Counter1,[String]$ItemValues)
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
} #end if
ELSEIF ($($ItemValues.count) -gt 1) {
Write-Host "DEBUG Info - Read-ConfigFile: Found $($ItemValues.count) Array Item(s)!"
Write-Host "DEBUG Info - Read-ConfigFile: Setting Variable: $($ItemName+$Counter1)"
Write-Host "DEBUG Info - Read-ConfigFile: with Value(s) -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: in Datatyp: Array"
Set-Variable -Name ($ItemName+$Counter1) -Value @([Array]$ItemValues) -Scope Global
$Profiles.Add($ItemName+$Counter1,[Array]$ItemValues)
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
} #end elseif
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: Found $($ItemValues.count) Array Item(s)!"
Write-Host "DEBUG Info - Read-ConfigFile: Setting Variable: $($ItemName+$Counter1)"
Write-Host "DEBUG Info - Read-ConfigFile: with Value(s) -> $ItemValues"
Write-Host "DEBUG Info - Read-ConfigFile: in Datatyp: $($ItemValues.gettype() | Select BaseType)"
Set-Variable -Name ($ItemName+$Counter1) -Value $ItemValues -Scope Global
$Profiles.Add($ItemName+$Counter1,$ItemValues)
Write-Host "DEBUG Info - Read-ConfigFile: ------------------------------"
} #end else
} #end if
} #end foreach
#Return how many Profiles were are created!
Return $Profiles
} #end elseif
#That shouldnt be happen...
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: Error reading ConfigValues!"
Write-Host "DEBUG Info - Read-ConfigFile: Exiting, because of this Issue."
Write-Host $Error
EXIT
} #end else
} #end elseif
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: That is impossible..."
Write-Host "DEBUG Info - Read-ConfigFile: You are not looking for Lines!?"
Write-Host "DEBUG Info - Read-ConfigFile: Have you unauthorized change the Modul Parameter???"
EXIT
} #end else
} #end elseif
ELSE {
Write-Host "DEBUG Info - Read-ConfigFile: Invalid ConfigValues from ConfigFile!"
Write-Host "DEBUG Info - Read-ConfigFile: Please check the Description of this Function"
Write-Host "DEBUG Info - Read-ConfigFile: and the ConfigFile!"
} #end else
} #end process
} #end function