Tags: Datei-Management, PowerShell
PowerShell bietet Cmdlets, die das Verarbeiten von CSV-Daten stark vereinfachen. Damit lässt sich das mühselige Parsen mit Hilfe von RegEx oder Substring-Operationen vermeiden. Die Spalten von CSV-Dateien werden stattdessen als Attribute von Objekten angesprochen, die man auf diese Weise filtern oder sortieren kann.
CSV ist nach wie vor das Austauschformat schlechthin, beispielsweise um Daten aus diversen Applikationen in Excel zu importieren. Eine häufige Anwendung von PowerShell besteht darin, Systeminformationen zu extrahieren, wobei diese meistens als Listen oder Tabellen ausgegeben werden. Eine unkomplizierte Konvertierung in CSV erlaubt ihre Analyse in einer Tabellenkalkulation.
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ücksichtigen.
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]).
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 weiterverarbeiten 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überschriften, 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 dazugehö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überschriften mit den Namen der Parameter von New-ADUser übereinstimmen. 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 Vergleichsausdruck 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
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