Konfigurationsdateien, Exporte, Management-Pack-Fragmente: Wer XML per Skript erzeugt, sollte keine Zeichenketten zusammenkleben. Mit dem XmlWriter entsteht gültiges, eingerücktes XML – so geht es richtig.
XML per Zeichenkettenverkettung zu erzeugen, geht so lange gut, bis ein Wert ein &, ein < oder ein Anführungszeichen enthält. Spätestens dann ist die Datei ungültig. Ein Community-Mitglied hat deshalb sein bewährtes Snippet mit dem .NET-XmlWriter geteilt – nach eigener Aussage „nach viel Gefummel endlich stabil“.
Die moderne Variante
Statt der älteren Klasse XmlTextWriter empfiehlt sich heute XmlWriter.Create mit expliziten Einstellungen. Ein try/finally stellt sicher, dass die Datei auch bei Fehlern geschlossen wird:
$path = 'C:\Temp\export.xml'
$settings = New-Object System.Xml.XmlWriterSettings
$settings.Indent = $true
$settings.IndentChars = ' '
$settings.Encoding = New-Object System.Text.UTF8Encoding($false) # UTF-8 ohne BOM
$writer = [System.Xml.XmlWriter]::Create($path, $settings)
try {
$writer.WriteStartDocument()
$writer.WriteStartElement('Konfiguration')
$writer.WriteAttributeString('Version', '1.0')
foreach ($server in 'SRV01', 'SRV02') {
$writer.WriteStartElement('Server')
$writer.WriteAttributeString('Name', $server)
$writer.WriteElementString('Rolle', 'Webserver & API') # & wird automatisch maskiert
$writer.WriteEndElement()
}
$writer.WriteEndElement()
$writer.WriteEndDocument()
}
finally {
$writer.Dispose()
}
Ergebnis:
<?xml version="1.0" encoding="utf-8"?>
<Konfiguration Version="1.0">
<Server Name="SRV01">
<Rolle>Webserver & API</Rolle>
</Server>
<Server Name="SRV02">
<Rolle>Webserver & API</Rolle>
</Server>
</Konfiguration>
Worauf Sie achten sollten
- Jedes
WriteStartElementbraucht einWriteEndElement. Bei Schleifen am besten direkt paarweise schreiben. WriteRawnur bewusst einsetzen: Es schreibt ungeprüften Text. Fehlerhafte Inhalte machen das Dokument ungültig.- Methoden mit Klammern aufrufen:
$writer.Flushohne Klammern gibt in PowerShell nur die Methodendefinition aus, statt sie auszuführen – ein häufiger Fehler, der auch im ursprünglichen Snippet steckte. - Kodierung festlegen: Für die meisten Zielsysteme ist UTF-8 ohne BOM die beste Wahl.
Alternativen
Für kleine, einfache Strukturen ist auch das [xml]-Objekt praktisch: Vorlage laden, Knoten mit CreateElement ergänzen, mit .Save() speichern. Für große Datenmengen ist der XmlWriter jedoch deutlich speicherschonender, weil er direkt in die Datei schreibt.
Heute
Das Beispiel funktioniert in Windows PowerShell 5.1 und PowerShell 7.