Ini-Dateien lesen "für Arme" (aktualisiert)

Hin und wieder geistern sie noch durch die „Admin-Szene“, die Ini-Dateien. Offiziell kann die PowerShell nichts mit ihnen anfangen, inoffziell gibt es diverse „Hacks“, die die Windows-API-Funktion GetPrivateProfileString aufrufen, in dem sie C#-Code in einen Here-String einsetzen, der dann während der Ausführung des Skripts kompiliert und ausgeführt wird. Mir sind solche Lösungen deutlich zu kompliziert. Ich bevorzuge das, was die PowerShell von Haus aus mitbringt. Das folgende kleine Skript liest einfach alle Sektionen einer Ini-Datei und danach alle Einträge in einer Sektion:

# Ini-Dateien lesen für „Arme“
$R = [RegEx]“(?<Key>^.+)=(?<Value>.+$)“
$Zeilen = get-content Test.ini
$i=0
while ($i-lt$Zeilen.Length)
{
$Zeile = $Zeilen[$i]
if ($Zeile -match „\[\w+\]“)
{
write-host -fore yellow $Zeile
# Jetzt alle Zeilen lesen bis zum nächsten Eintrag/EOF
do
{
$i++
$Res = $R.Match($Zeilen[$i])
if ($Res.Success)
{
write-host -fore green „Name: $($Res.Groups[‚Key‘].Value) – Value: $($Res.Groups[‚Value‘].Value)“
}
}
until (($Zeilen[$i] -match „\[\w+\]“) -or ($i -eq $Zeilen.Length))
}
}

Etwas komfortabler ist die folgende Funktion get-ini, der man Name der Ini-Datei, den Namen einer Sektion und den eines Eintrags übergibt, und die, sofern vorhanden, den Wert des Eintrags zurückgibt:

function get-ini
{
param([string]$IniDatei,
[string]$Eintrag,
[string]$Key)
# Erst Eintrag suchen
$R = [RegEx]“^$Key=(?<Value>.+$)“
$Zeilen = get-content $IniDatei
$i=0
while ($i-lt$Zeilen.Length)
{
$Zeile = $Zeilen[$i]
if ($Zeile -match „\[$Eintrag\]“)
{
write-debug $Zeile
do
{
$i++
$Res = $R.Match($Zeilen[$i])
if ($Res.Success)
{
return $($Res.Groups[‚Value‘].Value)
}
}
until (($Zeilen[$i] -match „\[\w+\]“) -or ($i -eq $Zeilen.Length))
}
$i++
}
}

PS: Die Funktion enthielt einen kleinen Fehler, der aber anscheinend niemanden aufgefallen ist (bzw. es hatte sich bislang niemand beschwert, was wie immer verschiedene Gründe haben kann).

PSPS: Wie sieht es mit der Unterscheidung auf Groß/Kleinschreibung aus bzw. wie lässt sich diese „deaktivieren“?

In diesem Fall würde ich die Shared-Variante der Match-Methode der RegEx-Klasse benutzen, der neben dem zu untersuchenden Text und dem regulären Ausdruck auch eine Option übergeben werden kann:

$Res = [Regex]::Match($Zeilen[$i],“^$Eintrag=(?<Wert>.+$)“, „IgnoreCase“)

Schreibe einen Kommentar

Bitte logge dich mit einer dieser Methoden ein, um deinen Kommentar zu veröffentlichen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s