Meister Import-Csv und andere CSV-Befehle in PowerShell

Das PowerShell-Cmdlet Export-Csv und das PowerShell-Cmdlet Import-Csv ermöglichen es Administratoren, CSV-Dateien über eine foreach-Schleife zu importieren, Export-Csv zum Anhängen von CSVs und zum Exportieren von Arrays in eine CSV-Datei und vieles mehr zu verwenden.

In diesem Artikel erfahren Sie mehr über häufige Szenarien, in denen Sie PowerShell verwenden können, um CSV-Dateien zu verwalten, wie zum Beispiel:

  • Lesen von CSV-Dateien mit PowerShell
  • Speichern von CSV-Dateien mit PowerShell
  • Formatieren der Ausgabe vor dem Ausführen von Export-CSV
  • Anhängen an eine CSV-Datei
  • Anhängen von Unterschieden an eine vorhandene Datei
  • Export-CSV und der #TYPE-String

Wenn Sie mit dem Innenleben von CSV-Dateien nicht vertraut sind, handelt es sich um Textdateien, die einem Standardformat folgen, bei dem die Werte in einer Tabelle durch Kommas getrennt werden. Sie können eine CSV-Datei in PowerShell mit dem Export-Csv-Cmdlet erstellen, indem Sie ein oder mehrere Objekte an dieses übergeben.

Der folgende Befehl findet die ersten beiden laufenden Prozesse und übergibt die generierten Objekte an das Export-Csv-Cmdlet. Das Export-Csv-Cmdlet erstellt dann eine CSV-Datei mit dem Namen processes.csv im Stammverzeichnis Ihres Systemlaufwerks (wahrscheinlich C:\).

PS51> Get-Process | Select-Object -First 2 | Export-CSV -Path "$env:SystemDrive\processes.csv"

Öffnen Sie nun processes.csv mit dem Notepad. Sie sollten oben die Überschriften "Name","SI","Handles","VM" sehen. Sie werden auch #TYPE System.Diagnostics.Process sehen, was jetzt vielleicht nicht viel Sinn ergibt. Keine Sorge, wir werden diese Zeichenkette in diesem Artikel behandeln.

Lesen von CSV-Dateien mit Import-Csv

Möchten Sie weitere Tipps wie diesen? Schauen Sie sich meinen persönlichen PowerShell-Blog an.

PowerShell hat ein paar Befehle, mit denen Sie Textdateien lesen können. Diese Befehle sind Get-Content und Import-Csv. Jeder dieser beiden Befehle liest die Datei technisch gesehen auf die gleiche Weise. Aber Import-Csv geht noch einen Schritt weiter. Import-Csv versteht die zugrunde liegende Struktur nicht nur einer Textdatei, sondern auch einer CSV-Datei.

Da eine CSV-Datei ein bestimmtes Schema hat, versteht Import-Csv das CSV-Schema. Dieser Befehl liest nicht nur die Textdatei von der Festplatte, sondern konvertiert auch die Zeilen in der CSV-Datei in PowerShell-Objekte.

Nicht-CSV-Dateien

In der Regel ist ein CSV-Datensatz durch Kommas getrennt, aber es gibt Zeiten, in denen ein CSV (technisch gesehen kein CSV mehr) durch ein anderes Trennzeichen getrennte Daten enthält. Diese Trennzeichen sind manchmal ein Tabulator oder vielleicht ein Semikolon.

Wenn Sie eine CSV-Datei mit einem anderen Trennzeichen haben, können Sie den Delimiter-Parameter verwenden. Dieser Parameter gibt an, dass Import-Csv nicht nach Kommas suchen soll, was es standardmäßig tut, sondern nach einem anderen Wert.

Zum Beispiel können Sie eine tabulatorgetrennte Datei wie folgt lesen:

PS51> Import-Csv -Path tab-separated-data.csv -Delimiter "`t"

Hinzufügen von Überschriften

A common Import-Csv parameter is Header. This parameter lets you specify the property names of the objects created by this cmdlet.

Standardmäßig behandelt das Import-Csv-Cmdlet die oberste Zeile der CSV-Datei als Überschriften. Es konvertiert dann diese Werte in Eigenschaften jeder Zeile (Objekt). Wenn Sie jedoch eine CSV-Datei haben, die keine Überschriften enthält, können Sie den Header-Parameter verwenden, um selbst eine Überschrift festzulegen.

Der Header-Parameter verhindert, dass Import-CSV Ihre erste Zeile als Überschrift verwendet, und erspart Ihnen die Mühe, die CSV-Datei manuell zu öffnen, um Überschriften hinzuzufügen.

Um dieses Verhalten zu demonstrieren, öffnen Sie den Notepad und kopieren Sie den unten stehenden Text. Dieser Text stellt einen Datensatz mit drei Zeilen und zwei Spalten dar.

a,1
b,2
c,3

Speichern Sie die Textdatei als test.csv. Vergessen Sie nicht, die Dateierweiterungen zu aktivieren oder die Datei in Anführungszeichen zu setzen, damit Sie sie nicht versehentlich als Datei mit der Erweiterung .csv.txt speichern!

Verwenden Sie nun Import-CSV, um die kürzlich erstellte CSV-Datei ohne den Header-Parameter zu lesen und überprüfen Sie die Ausgabe.

PS51> Import-Csv .\test.csv

a 1
---
b 2
c 3

Beachten Sie, dass die erste Zeile als Eigenschaften des Objekts verwendet wurde. A und 1 sind keine „Beschriftungen“, die Sie für die Eigenschaften des Objekts möchten. A, b und c sind Buchstaben, während 1, 2 und 3 Zahlen sind. Sie müssen diese mit dem Parameter Header wie folgt definieren:

PS51> Import-Csv .\test.csv -Header "Letter", "Number"

Letter Number
------ ------
a      1
b      2
c      3

Speichern von CSV-Dateien mit PowerShell

Wenn Sie aus PowerShell-Objekten eine CSV-Datei erstellen oder speichern müssen, können Sie auch den umgekehrten Weg gehen. Während der Import-Csv-Befehl eine CSV-Datei in PowerShell-Objekte „umwandelt“, macht der Export-Csv-Befehl das Gegenteil. Dieser Befehl „wandelt“ PowerShell-Objekte in eine CSV-Datei um.

Das Speichern einer CSV-Datei mit Export-Csv ermöglicht es Ihnen, diese Daten später in anderen Systemen anzuzeigen oder zu verwenden.

Zum Beispiel kann ich alle laufenden Prozesse auf meinem Computer speichern, indem ich Get-Process an den Export-Csv-Befehl pipen.

PS51> Get-Process | Export-Csv -Path processes.csv

Der Export-Csv-Befehl ist einfach, aber es gibt ein paar Dinge, auf die Sie achten sollten.

Ausgabeformatierung vor dem Ausführen von Export-CSV

Wie Sie oben gesehen haben, führt Export-Csv alleine eine „rohe“ Konvertierung durch. Es fügt keine spezielle Rich-Text-Formatierung hinzu, fügt keine Farben hinzu usw.

Einer der häufigsten Stolpersteine besteht darin, die Ausgabe vor dem Exportieren in eine CSV-Datei besser aussehen zu lassen. Viele Benutzer versuchen, die Ausgabe vor dem Exportieren in eine CSV-Datei zu verbessern. Aber ich werde Ihnen gleich zeigen, dass dies die Dinge verschlimmern kann.

Sie können eine CSV-Datei in Microsoft Excel öffnen und kursivieren, fett markieren, Farben hinzufügen und viele andere Dinge tun. Wenn Sie die Datei jedoch als CSV (anstelle einer Excel-Arbeitsmappe) speichern, werden alle Formatierungen gelöscht. Eine CSV-Datei ist einfach nicht „intelligent“ genug.

Beachten Sie, dass CSV-Dateien einfach nur Textdateien mit Werten sind, die durch Kommas (oder manchmal durch Tabs) getrennt sind. Das Piping von Import-Csv zu einem Format-*-PowerShell-Cmdlet funktioniert nicht wie erwartet.

Gemäß der Microsoft Export-Csv-Dokumentation: „Formatieren Sie Objekte nicht, bevor Sie sie an das Export-CSV-Cmdlet senden. Wenn das Export-CSV-Cmdlet formatierte Objekte erhält, enthält die CSV-Datei die Formatierungseigenschaften anstelle der Objekteigenschaften.“

Warum ist das so?

Öffnen Sie ein PowerShell-Fenster und erstellen Sie einige Dummy-Daten. Verwenden Sie das Beispiel Get-Process, das im ersten Abschnitt dieses Artikels behandelt wurde. Weisen Sie diesmal die Ausgabe einer Variablen zu. Leiten Sie dann diese Prozessobjekte an das Format-Table-Cmdlet weiter.

PS51> $a = Get-Process
PS51> $a | Format-Table
Using Format-Table

Sie können sehen, dass Sie mit Format-Table eine saubere, tabellarische Ausgabe haben.

Speichern Sie diese Ausgabe nun in einer anderen Variablen.

PS51> $b = $a | Format-Table

Sehen Sie sich nun die Eigenschaften der Variablenwerte $a und $b mit Get-Member an. Dieses Cmdlet hilft Ihnen zu verstehen, warum diese beiden scheinbar gleichartigen Objekte nicht auf die gleiche Weise in eine CSV-Datei exportiert werden.

PS51> $a | Get-Member
System.Diagnostics.Process object type
PS51> $b | Get-Member
Format-Table‘s many object types

Die Ausgabe direkt von Get-Process lautet: TypeName: System.Diagnostics.Process, während die Ausgabe von Format-Table völlig unterschiedlich ist. Es werden viele verschiedene Typen mit unterschiedlichen Eigenschaften zurückgegeben.

Wenn Sie $a und $b in der Konsole anzeigen, sieht die Ausgabe identisch aus. Dieses Verhalten ist auf das Formatierungssystem von PowerShell zurückzuführen.

Wie wirkt sich dies auf die Ausgabe von Export-Csv aus?

PS51> $b | Export-Csv | Format-Table

Export-Csv liest jedes Objekt so wie es ist. Wenn Sie die Ausgabe an ein Format-*-Cmdlet weiterleiten, ändern Sie die Eingabe, die Export-Csv erhält. Dies wirkt sich dann auf die Ausgabe aus, die in Ihrer neuen CSV-Datei gespeichert wird.

Wenn Sie die Ausgabe an das Export-Csv-Cmdlet weiterleiten möchten, leiten Sie die Ausgabe nicht an ein beliebiges Format-*-Cmdlet weiter.

Denken Sie daran, dass CSV-Dateien sich auf Daten, nicht auf die Formatierung konzentrieren.

Anhängen an eine CSV-Datei

Manchmal möchten Sie möglicherweise eine vorhandene Datei ergänzen, anstatt eine völlig neue zu erstellen. Standardmäßig überschreibt Export-Csv jede über den Path-Parameter angegebene Datei.

Wenn Sie Daten an eine CSV anhängen möchten, verwenden Sie den Append-Parameter.

Angenommen, Sie haben eine Schleife, in der jedes verarbeitete Objekt in eine CSV-Datei gespeichert werden soll. Für jede Iteration haben Sie ein anderes Objekt, das Sie in einer CSV-Datei speichern möchten. Wenn Sie Export-Csv wiederholt aufrufen, wird die CSV-Datei überschrieben, wenn Sie den Append-Parameter nicht verwenden. Ohne den Append-Parameter erhalten Sie nur das letzte Objekt, was in den meisten Fällen nicht das gewünschte Ergebnis ist.

Das folgende Beispiel findet die ersten fünf laufenden Prozesse. Anschließend wird in einer PowerShell Import-Csv foreach-Schleife der Name– und ProductVersion-Eigenschaften nacheinander in die Datei test.csv aufgezeichnet.

Get-Process | Select-Object -First 5 | Foreach-Object {
    $_ | Select-Object Name, ProductVersion | Export-CSV -Path C:\test.csv -Append
}

Wenn Sie den Append-Parameter nicht verwenden, sehen Sie, dass nur der fünfte Prozess in der CSV-Datei angezeigt wird.

Anhängen von Unterschieden an eine CSV-Datei

Sie können mit Export-Csv nur Eigenschaftsunterschiede an eine vorhandene CSV-Datei anhängen. Dies bedeutet, dass, wenn die Spalten einer CSV-Zeile und das aufzuzeichnende Objekt unterschiedlich sind, diese trotzdem angehängt werden.

Um nur Unterschiede an die CSV-Datei anzuhängen, müssen Sie die Parameter Append und Force zusammen verwenden. Laut Microsoft-Dokumentation „Wenn die Parameter Force und Append kombiniert werden, können Objekte mit nicht übereinstimmenden Eigenschaften in eine CSV-Datei geschrieben werden. Nur die übereinstimmenden Eigenschaften werden in die Datei geschrieben. Die nicht übereinstimmenden Eigenschaften werden verworfen.“

Um dies zu zeigen, erstelle ein Objekt mit zwei Eigenschaften; Name und Alter.

PS51> $Content = [PSCustomObject]@{Name = "Johnny"; Age = "18"}

Erstelle nun ein weiteres Objekt mit den Eigenschaften Name und PLZ.

PS51> $OtherContent = [PSCustomObject]@{Name = "Joe"; Zip = "02195"}

Jedes Objekt hat unterschiedliche Eigenschaften.

Erstelle anschließend eine CSV-Datei aus dem ersten Objekt und versuche, das zweite Objekt ohne den Force-Parameter an die CSV anzuhängen. Du erhältst einen Fehler.

PS51> $Content | Export-CSV -Path .\User.csv -NoTypeInformation
PS51> $OtherContent | Export-CSV -Path .\User.csv -NoTypeInformation -Append
Export-Csv without Force

Verwendest du jedoch den Force-Parameter, funktioniert Export-Csv einwandfrei.

PS51> $OtherContent | Export-CSV -Path .\User.csv -NoTypeInformation -Append -Force

Beachte jedoch, dass die Spalte PLZ in der CSV-Datei fehlt. Verwende Force mit Vorsicht, da es möglicherweise nicht das beabsichtigte Ergebnis liefert.

PS51> Import-Csv -Path .\User.csv

Name   Age
----   ---
Johnny 18
Joe

Export-Csv und der #TYPE-String

Standardmäßig enthält eine CSV-Datei, die ohne zusätzliche Parameter mit Export-Csv erstellt wurde, einen #TYPE-String am Anfang. Dieser String wird durch den Typ des von Export-Csv erhaltenen Objekts gefolgt.

#TYPE System.Diagnostics.Process

In den meisten Fällen ist dieser String beim Verwenden der Ausgabe nicht wirklich nützlich. Dieser String ist nur vorhanden, falls du den Typ des Objekts beibehalten musst, aus dem die Eigenschaften und Werte stammen.

Um diesen String zu entfernen, verwende den Parameter NoTypeInformation. Dieser Parameter entfernt den String vollständig aus der CSV-Datei.

Beachte, dass dies in PowerShell Core nicht mehr notwendig ist.

Zusammenfassung

Mit den Import-CSV und Export-CSV PowerShell-Cmdlets können Sie einfach mit CSV-Dateien arbeiten. Diese beiden nützlichen Cmdlets sollten Sie häufig verwenden, wenn Sie mit Objekten und CSV-Dateien arbeiten.

Meine Hoffnung ist, dass Sie mit den Erklärungen und Beispielen, die ich hier dargestellt habe, ein klares Verständnis dafür haben, in welchen Situationen Sie diese Cmdlets zu Ihrem Vorteil nutzen können.

Möchten Sie mehr Tipps wie diese? Schauen Sie sich meinen persönlichen PowerShell-Blog an.

Source:
https://adamtheautomator.com/import-csv/