CSV-Dateien in PowerShell erstellen, sortieren, filtern


    Tags: ,

    Import von CSV-DatenPowerShell bietet Cmdlets, die das Verar­beiten von CSV-Daten stark verein­fachen. Damit lässt sich das müh­selige Parsen mit Hilfe von RegEx oder Substring-Opera­tionen ver­meiden. Die Spalten von CSV-Dateien werden statt­dessen als Attribute von Objekten ange­sprochen, die man auf diese Weise filtern oder sortieren kann.

    CSV ist nach wie vor das Austauschformat schlechthin, beispiels­weise um Daten aus diversen Applikationen in Excel zu importieren. Eine häufige Anwendung von PowerShell besteht darin, System­informationen zu extrahieren, wobei diese meistens als Listen oder Tabellen ausgegeben werden. Eine unkomplizierte Konvertierung in CSV erlaubt ihre Analyse in einer Tabellen­kalkulation.

    Daten in CSV konvertieren

    Dieser Aufgabe übernehmen die Cmdlets Export-CSV und Convertto-CSV. Beide verwandeln tabellarische in kommaseparierte Daten, wobei diese vorher ausdrücklich nicht mit Format-Table aufbereitet werden sollen.

    Der wesentliche Unterschied besteht darin, dass Convertto-CSV seinen Output auf stdout ausgibt, während Export-Csv zusätzlich die Funktion von Set-Content bietet. Es ist daher in Lage, CSV-Daten in eine Datei zu schreiben und dabei verschiedene Optionen zu berück­sichtigen.

    Dazu zählen die Schalter Append und NoClobber, um Daten an bestehende Dateien anzuhängen bzw. das Schreiben zu verweigern, wenn diese schon existieren. Außerdem kann man mit dem Parameter Encoding den Zeichensatz festlegen (Standard ist ASCII).

    AD-Benutzer in CSV-Datei schreiben

    Möchte man beispielsweise alle Benutzer aus dem Active Directory in eine CSV-Datei schreiben, die der OU Sales angehören, dann könnte man diesen Befehl verwenden:

    Get-AdUser -Filter * -SearchBase "OU=Sales,DC=contoso,DC=de" |
    Export-Csv -Path .\users-sales.csv -NoClobber

    Beide Cmdlets fügen als Trennzeichen zwischen den Spalten standardmäßig ein Komma ein. Dieses kann man über den Parameter Delimiter anpassen, indem man für das obige Beispiel etwa ein Semikolon wählt:

    Get-AdUser -Filter * -SearchBase "OU=Sales,DC=contoso,DC=de" |
    Export-Csv -Path .\users-sales.csv -NoClobber -Delimiter ";"

    Möchte man als Trennzeichen einen Tabulator verwenden, dann bedient man sich der Notation -Delimiter (9 -as [char]).

    Ausgewählte Attribute von AD-Konten im CSV-Format ausgeben.

    Standardmäßig schreiben beide Cmdlets Informationen über den Objekt- bzw. Datentyp an den Anfang der CSV-Tabelle, um die Rückumwandlung mit Hilfe von Import-Csv bzw. Convertfrom-Csv zu erleichtern. Dies kann man durch Angabe des Schalters NoTypeInformation verhindern.

    CSV-Daten importieren

    Die zwei Gegenspieler von Export-Csv und Convertto-Csv lassen sich überall dort nutzen, wo man CSV-Daten einlesen und weiter­verarbeiten möchte. Sowohl ConvertFrom-Csv als auch Import-Csv gehen davon aus, dass es sich beim Trennzeichen um ein Komma handelt. Ist das nicht der Fall, dann muss man es über den Parameter Delimiter angeben.

    Importiert man eine CSV-Datei, dann kann man anschließend jede Spalte über den Namen der Überschrift ansprechen. Fehlt eine solche, dann nimmt Import-Csv bzw. ConvertFrom-Csv einfach die Werte des ersten Datensatzes, was in der Regel aber nicht erwünscht sein dürfte.

    Hat man beispielsweise eine Liste mit den Feldern Vorname, Name und Mail, die in der Datei subscribers.csv gespeichert ist, dann kann man sie mit diesem Befehl einlesen:

    $a = Import-Csv -Path '.\subscribers.csv'

    Anschließend kann man die Spalte mit den Namen über

    $a.Name

    oder mit den Mail-Adressen über

    $a.Mail

    ausgeben.

    Enthält die CSV-Datei keine Spaltenüber­schriften, dann kann man die Bezeichner für die Felder mit Hilfe des Parameters Header nachreichen:

    $a = Import-Csv -Path '.\subscribers.csv' -Header "Vorname","Name", "Mail"

    AD-Benutzer aus CSV-Tabelle erstellen

    Um beim Beispiel mit den AD-Benutzern zu bleiben, ist es eine gängige Anwendung, eine größere Zahl an Konten anzulegen, indem man die dazuge­hörigen Daten aus einer Excel-Tabelle liest und an New-ADUser übergibt:

    Import-Csv .\users.csv | New-ADUser

    Beim Aufbau der CSV-Datei ist darauf zu achten, dass die Spalten­über­schriften mit den Namen der Parameter von New-ADUser überein­stimmen. Außerdem darf die Datei keine Type-Information enthalten, wie sie PowerShell beim Export einfügt.

    Wenn man das Passwort der Benutzerkonten vorbelegen möchte, dann kann man das nicht über ein Feld in der CSV-Datei tun, weil New-ADUser nur einen SecureString akzeptiert. Daher muss man nach dem Muster

    Import-Csv .\user.csv |
    New-ADUser -AccountPassword (ConvertTo-SecureString "P@ssw0rd" -AsPlainText -force)

    vorgehen.

    CSV-Daten sortieren und filtern

    Da man die Spalten einer CSV-Datei nach dem Import über ihre Namen ansprechen kann, fällt es relativ einfach, die Daten zu sortieren. Beim obigen Beispiel einer Liste mit den Kolumnen Vorname, Name und Mail ließe sich die Datei mit diesem Befehl nach Namen sortieren:

    Import-Csv -Path '.\subscribers.csv' | sort -Property "Name"

    Dabei stehen alle Möglichkeiten von Sort-Object zur Verfügung, wie etwa das Sortieren in absteigender Reihenfolge oder das Entfernen von Dubletten.

    Analog dazu funktioniert das Filtern von Spalten mit Hilfe von Select-Object:

    Import-Csv -Path '.\subscribers.csv' | select Mail, Name

    In diesem Fall würden nur die Spalten Mail und Name angezeigt.

    Möchte man nur bestimmte Zeilen in das Ergebnis übernehmen, dann muss man in Regel einen Vergleichs­ausdruck bemühen:

    Import-Csv -Path '.\subscribers.csv' | ? Mail -like *meier*

    Dieses Beispiel würde alle Datensätze übernehmen, deren Mail-Adresse die Zeichenkette "meier" enthält.

    Möchte man eine CSV-Datei auf diese Weise vertikal oder horizontal filtern und das Ergebnis speichern, dann muss man es mit Export-Csv wieder zurückschreiben:

    Import-Csv -Path .\subscribers.csv | ? email -like *meier* | Export-Csv sb.csv

    Dieser Befehl würde die Einträge mit "meier" in der Mail-Adresse in eine Datei namens sb.csv exportieren.

    Täglich Know-how für IT-Pros mit unserem Newsletter

    Wir ver­wenden Ihre Mail-Adresse nur für den Ver­sand der News­letter.
    Es erfolgt keine per­sonen­be­zogene Auswertung.

    Bild von Wolfgang Sommergut
    Wolfgang Sommergut hat lang­jährige Erfahrung als Fach­autor, Berater und Kon­ferenz­sprecher zu ver­schie­denen Themen der IT. Da­ne­ben war er als System­ad­mi­ni­stra­tor und Con­sultant tätig.
    // Kontakt: E-Mail, XING, LinkedIn //

    Verwandte Beiträge

    Weitere Links

    1 Kommentar

    wie können die Header bei Export-Csv sortiert werden?

    Das neue Object heißt:

    $newobj = New-Object psobject -Property @{
    Number = $number
    Name = $s.Name
    Address = $a.Address
    }

    Ein anschließendes

    $newobj | export-csv test.csv -notypeinformation -Delimiter ";" -Append

    sortiert den Inhalt leider nur alphabetisch