2017-07-10 4 views
1

Ich arbeite an einem PowerShell-Skript zum automatischen Upgrade der installierten Komponenten. Die Konfigurationsdetails der Datei werden in einer XML-Datei gespeichert. Da in den Variablen eine gegenseitige Abhängigkeit besteht, sind die Variablen wie folgt definiert.XML-Variablenaustausch mit PowerShell

<root> 
    <variable name="APP_NAME", value="My App" /> 
    <variable name="INSTALL_PATH", value="some folder/${APP_NAME}" /> 
    <variable name="PRODUCT_HOME" value="${INSTALL_PATH}\productinfo\${APP_NAME}" /> 
<root> 

Wenn ich die XML-Datei lesen möchte ich den Wert von $INSTALL_PATH als some folder/My App statt some Folder/${APP-NAME} zu bekommen. Und der Wert von APP_NAME ändert sich nach wenigen Schritten und ich muss die XML-Datei erneut analysieren.

Was wäre der beste Weg, es zu tun?

Ich dachte, die XML-Datei zu lesen und PowerShell-Variablen für jede Variable in der XML-Datei zu erstellen und wenn ich die XML-Datei erneut analysieren muss, werde ich die Werte der Variablen ändern.

Gibt es einen besseren Weg, dies zu erreichen?

+0

Sie schreiben effektiv Ihre eigene kleine Domänensprache in XML. Wenn Sie dies nicht einschränken (das heißt, es ist legal, dass Definitionen in einer beliebigen Reihenfolge angezeigt werden), müssen Sie die vollständige Aufgabe übernehmen und eine DAG erstellen und topologisch sortieren. Ich empfehle dringend, dies nicht zu tun und Definitionen nur in der Reihenfolge zuzulassen. In diesem Fall können Sie die Datei Zeile für Zeile analysieren und einen Hash der Definitionen beibehalten, die in jeder Zeile ersetzt werden. –

+1

Eine noch fauligere, aber möglicherweise effektive Alternative ist die Anforderung, dass die Konfiguration * ein PowerShell-Objekt sein soll, das Sie von einem Dot-Source-Skript erhalten. Der Vorteil ist, dass es den Benutzern volle Flexibilität beim Aufbau der Konfiguration ermöglicht. Der Nachteil ist, dass es den Benutzern volle Flexibilität beim Aufbau der Konfiguration ermöglicht - es ist Code, der gepflegt und verstanden werden muss und möglicherweise Auswirkungen auf die Sicherheit haben kann. –

+0

Last but not least (OK, ich schätze, ich hätte meine Zeit damit verbringen sollen, eine Antwort zu schreiben), stellen Sie sicher, dass Sie das Rad nicht auf irgendeine Weise neu erfinden. In PowerShell gibt es (halb-) native Unterstützung für die Wartung von Komponenten in der Form [Konfiguration des gewünschten Status] (https://msdn.microsoft.com/en-us/PowerShell/dsc/overview). Es kann für Ihre Zwecke übertrieben sein, oder es kann eine zukunftssichere Lösung sein, die besser ist als die eigene. –

Antwort

1

Wenn die <variable> Knoten „in Ordnung“ sind, dh jeder Knoten verwendet nur Variablen, die bereits in früheren Knoten definiert wurden, können Sie so etwas tun könnte:

$xml.SelectNodes('//variable') | ForEach-Object { 
    New-Variable -Name $_.name -Value $ExecutionContext.InvokeCommand.ExpandString($_.value) 
} 

Sonst werden müssen Sie definieren die Variablen zuerst, und die verschachtelten Variablen in einem zweiten Schritt erweitern:

$nodes = $xml.SelectNodes('//variable') 

$nodes | ForEach-Object { 
    New-Variable -Name $_.name -Value $_.value 
} 

$nodes | Select-Object -Expand name | ForEach-Object { 
    $var = Get-Variable -Name $_ 
    $var.Value = $ExecutionContext.InvokeCommand.ExpandString($var.Value) 
} 

Beachten Sie, dass eine hashtable statt einzelner Variablen tendiert die Handhabung viel einfacher zu machen.