nox309
Goto Top

Powershell Update-Vergleichen von Ini Datein

Guten Abend zusammen,

Ich brauche mal einen Denkanstoß oder auch Hilfe.

Folgende Situation:
Zur Standardisierung/Automation von div. sich wiederholenden Aufgaben schreibe ich eine Sammlung von PowerShell Scripten (auch um mich mehr mit dem Thema komplexerer Skripte auseinander zusetzten, einfache dinge sind kein Problem). Eines dieser Scripte holt aus einer Config ini Datei div. Variablen und stellt diese global zur Verfügung. Sollte diese Datei nicht vorhanden sein, erstellt es diese auch.
Jetzt kann es sein das einer der Kollegen ggf. eine andere Config haben will wie z.B. das Log Level etc.

Nun ist mein Problem das ich diese Ini Datei ja ggf. mal Updaten muss da neu Variablen/Funktionen hinzukommen.
Ich versuche also gerade irgendwie diese zu Updaten, ohne dass ggf. veränderte Werte zurückgesetzt werden.
Klar kann ich meinen Kollegen diese Infos geben und sie müssen ihre Config Updaten, mir geht es aber mehr um den Weg als das Ziel, will wie gesagt primär an/mit dem Projekt lernen.

Mein bisheriger versuch mit einer Sample Datei zu arbeiten und dann beide zu vergleichen und ggf. fehlende Werte hinzuzufügen gelingt mir zwar, aber die gesamte Formatierung geht dabei flöten, ebenso die Reihenfolge der Daten.

Kurz um Ziel erfühlt, aber es gefällt mir nicht und denke das müsste doch einfacher gehen.
Ggf. kann mir einer von euch den richtigen Hinweis geben. Vielleicht ist mein Gedanke mit den Variablen aus einer Ini auch komplett doof und es gibt einfachere und schönere Wege, dann lerne ich gerne dazu.


Danke euch schon mal vor ab.
Grobes Aussehen der ini Datei:
[Settings]
Version=0.1
;the log path must be writable by every user
Logpath=.\log\
;allowed values for the log level 'Information', 'Warning', 'Error', 'Debug  
Loglevel=Information
ConsolenOutput=true
CloudUserCSVFilePath=.\conf\CloudUser.csv

[AD]
Domainname=test.local
ADServer=dc.test.local
SharedMailboxOU=OU=OU2,OU=OU1,DC=test,DC=local
DistributiongroupOU=OU=OU2,OU=OU1,DC=test,DC=local
DefaultUser=OU=OU1,OU=OU1,DC=test,DC=local
1SiteUserOU=OU=OU2,OU=OU1,DC=test,DC=local

Mein Update Code
function update-config {
    function Get-IniContent($filePath) {
        $iniContent = @{}  
        switch -regex -file $filePath {
            "^\[(.+)\]" {    
                $currentSection = $matches[1]  
                $iniContent[$currentSection] = @{}  
            }
            "(.+)=(.+)" {    
                $name, $value = $matches[1..2]  
                $iniContent[$currentSection][$name] = $value  
            }
        }
        return $iniContent  
    }
    $sampleIniPath = ".\conf\config.sample.ini"  
    $configIniPath = ".\conf\config.ini"  
    $sampleIni = Get-IniContent -filePath $sampleIniPath
    $configIni = Get-IniContent -filePath $configIniPath
    foreach ($section in $sampleIni.Keys) {
        if (-not $configIni.ContainsKey($section)) {
            $configIni[$section] = @{}  
        }
        foreach ($key in $sampleIni[$section].Keys) {
            if (-not $configIni[$section].ContainsKey($key)) {
                $configIni[$section][$key] = $sampleIni[$section][$key]
            }
        }
    }
    Set-Content -Path $configIniPath -Value ""  
    foreach ($section in $configIni.Keys) {
        Add-Content -Path $configIniPath -Value "[$section]"  
        $configIni[$section].GetEnumerator() | ForEach-Object {
            Add-Content -Path $configIniPath -Value "$($_.Key)=$($_.Value)"  
        }
    }
}

Content-ID: 71491844672

Url: https://administrator.de/contentid/71491844672

Ausgedruckt am: 14.11.2024 um 01:11 Uhr

8030021182
8030021182 06.11.2023 aktualisiert um 12:58:30 Uhr
Goto Top
ebenso die Reihenfolge der Daten.
Reihenfolge ist zwar in Ini-Dateien Schall und Rauch ... aber wenn du das unbedingt willst.
Du nutzt normale Hashtables, das sind per Default Dictionaries ohne definierte Reihenfolge der Keys.
Wenn du Hashtables mit "Order" also "OrderedDictionaries" haben willst musst du das der Hashtable auch sagen mittels [ordered] Keyword. Dann sind die Keys in der originalen Reihenfolge wie sie in der Datei stehen.
# hier
$iniContent = [ordered]@{}
# und hier
$iniContent[$currentSection] = [ordered]@{}
# und hier
$configIni[$section] = [ordered]@{}

Gruß Katrin
nox309
nox309 06.11.2023 um 14:59:45 Uhr
Goto Top
Reihenfolge ist zwar in Ini-Dateien Schall und Rauch ... aber wenn du das unbedingt willst.

Jaa das die Reihenfolge in INI Dateien Schall und Rauch sind ist mir bewusst, aber man findet Sachen schneller, wenn es Größer wird.

Aber danke dir, ich werde es heute Abend mal probieren.
8030021182
8030021182 06.11.2023 aktualisiert um 15:19:50 Uhr
Goto Top
Zitat von @nox309:
Jaa das die Reihenfolge in INI Dateien Schall und Rauch sind ist mir bewusst, aber man findet Sachen schneller, wenn es Größer wird.
Bei größeren Einstellungsdateien würde meine Wahl eher auf XML als Daten-Format fallen wenn man denn die Wahl hat.
Da ist das Parsing und spezifische Selektion um einiges effizienter und PS beherrscht es nativ.
nox309
nox309 06.11.2023 um 15:58:54 Uhr
Goto Top
Okay, dann gucke ich mir das auch noch mal an.
Danke dir
TK1987
TK1987 06.11.2023 um 16:17:10 Uhr
Goto Top
Moin,

du hast einen kleinen Fehler in deinem Skript:
Zitat von @nox309:
"(.+)=(.+)"  
Beachte, dass Quantifier im RegEx standardmäßig alles zutreffende verschlingen.

Wenn obiger RegEx zum Beispiel auf folgender Zeile deiner Ini angewendet wird:
DefaultUser=OU=OU1,OU=OU1,DC=test,DC=local
lautet das Ergebnis des von dir erstellten Hashtables:
Name                                 Value
----                                 -----
DefaultUser=OU=OU1,OU=OU1,DC=test,DC local

Du musst ein Fragezeichen hinter deinem Quantifier ergänzen, damit nur bis zum ersten Auftreten des "="-Zeichens gesucht wird.
"(.+?)=(.+)"  

Gruß Thomas