CSV-Daten mit Import-Csv und ForEach-Schleife in PowerShell verarbeiten

Haben Sie jemals dieselbe Aufgabe mehrmals erledigen müssen? Zum Beispiel das Erstellen mehrerer Active Directory-Benutzer einzeln über die GUI? Oder das Anmelden auf einem Server, um alte Protokolle aus ausgewählten Ordnern zu löschen? Wenn Ihre Antwort ja lautet, dann wissen Sie, dass Sie nicht allein sind. Es ist an der Zeit, den PowerShell-Befehl Import-Csv und die foreach-Schleife zu meistern.

Es ist nichts Falsches an manuellen Aufgaben; manchmal ist es notwendig. Aber wenn es darum geht, CSV-Dateien zu lesen und zu verarbeiten, können der PowerShell-Befehl Import-Csv und die foreach-Schleife helfen.

Der PowerShell-Befehl Import-Csv ist eine hervorragende Möglichkeit, Daten aus einer tabellarischen Quelle wie einer CSV-Datei zu lesen. Mit der foreach-Schleife können Sie dann über jede Zeile in den CSV-Daten iterieren.

In diesem Artikel lernen Sie, wie Sie diese leistungsstarke Kombination verwenden können, um Massen-, langweilige und repetitive Aufgaben zu automatisieren.

Wenn Sie neu beim Befehl Import-Csv und der foreach-Schleife sind oder eine Auffrischung dessen wünschen, was Sie bereits wissen, können Sie diese Links besuchen, um mehr zu erfahren.

CSV-Dateien in PowerShell verwalten mit Import-Csv (foreach-Schleife)

Zurück zu den Grundlagen: Die PowerShell foreach-Schleife

Voraussetzungen

In diesem Artikel gibt es mehrere Beispiele und Demos. Um mitzumachen, benötigen Sie zuerst ein paar Dinge.

  • A script editor such as Visual Studio Code, Atom, or Notepad++. Use whichever one you’re comfortable with.
  • Windows PowerShell 5.1 oder PowerShell Core 6+
  • Zugriff auf Exchange Online (optional, wenn Sie das Beispiel für Exchange Online praktisch durchführen möchten).

Import-Csv und die ForEach-Schleife in Aktion setzen

In den nächsten Abschnitten finden Sie mehrere Beispiele, wie Sie das Cmdlet Import-Csv und die ForEach-Schleife verwenden können, die Sie in realen Szenarien verwenden können. Während diese Beispiele zum Importieren von CSV-Dateien in PowerShell spezifisch für bestimmte Zwecke sind, ist es wichtig zu verstehen, dass das zugrunde liegende Konzept und die Technik gleich sind.

Auslesen und Anzeigen von Datensätzen aus CSV

Eine der grundlegendsten Verwendungen von Import-Csv und der ForEach-Schleife besteht darin, Datensätze aus einer Datei auszulesen und in der Konsole anzuzeigen. Die Struktur einer CSV-Datei ähnelt der einer Datenbank. Sie hat Spaltenüberschriften, und jede Zeile wird als Datensatz betrachtet.

Zum Beispiel enthält die Datei mit dem Namen employee.csv den folgenden Inhalt, der aus drei Spalten – EmployeeID, Name und Geburtstag – und vier Datensätzen besteht.

CSV containing employee records

Der folgende Code importiert den Inhalt der Datei employee.csv und leitet die importierten Daten an das Cmdlet ForEach-Object weiter. Anschließend durchläuft ForEach-Object jeden Datensatz in der importierten CSV-Datei und gibt die konkatenierten Werte in der Konsole aus. Kopieren Sie den folgenden Code und speichern Sie ihn als list-employee.ps1.

Hinweis: Die Art der ForEach-Schleife, die in diesem Beispiel verwendet wird, ist das ForEach-Object-Cmdlet. Lesen Sie den Abschnitt „Das ForEach-Object-Cmdlet“ in diesem Artikel.

Import-Csv .\employee.csv | ForEach-Object {
    Write-Host "$($_.Name), whose Employee ID is $($_.EmployeeID), was born on $($_.Birthday)."
}

Sobald das Skript gespeichert ist, führen Sie es aus, indem Sie den Dateinamen in PowerShell aufrufen. Wenn das Skript ausgeführt wird, sollte eine ähnliche Ausgabe wie im folgenden Screenshot angezeigt werden.

Imported CSV records displayed in the console

Suchen und Anzeigen von Datensätzen aus einer CSV-Datei

In dem vorherigen Beispiel haben Sie gelernt, wie Sie alle Datensätze aus einer CSV-Datei lesen und anzeigen können. In diesem Beispiel wird dieselbe CSV-Datei employee.csv verwendet, aber diesmal erstellen Sie eine PowerShell-Funktion, um nach einer EmployeeID in der CSV-Datei zu suchen.

Der folgende Codeausschnitt ist eine PowerShell-Funktion namens Find-Employee, die nur einen Parameter hat. Der Parametername lautet EmployeeID und er akzeptiert einen Wert für die Mitarbeiter-ID, nach dem in der CSV-Datei gesucht werden soll.

Damit diese Funktion verwendet werden kann, muss sie zuerst in Ihre PowerShell-Sitzung importiert werden. Es gibt zwei Möglichkeiten, die Funktion Find-Employee in den Speicher zu importieren:

  1. 1. Kopieren und Einfügen des folgenden Codes in PowerShell.
  2. 2. Speichern des Skripts als Find-Employee.ps1 und Importieren mit der dot-sourcing-Technik.

Hinweis: Der in diesem Beispiel verwendete Typ der ForEach-Schleife ist die ForEach-Anweisung. Siehe den Abschnitt „Die foreach-Anweisung“ in diesem Artikel.

Function Find-Employee {
    param (
        # Der Parameter nimmt die Mitarbeiter-ID an, nach der gesucht werden soll.
        [Parameter(Mandatory)]
        $EmployeeID
    )

    # Importieren Sie den Inhalt der employee.csv-Datei und speichern Sie ihn in der Variablen $employee_list.
    $employee_list = Import-Csv .\employee.csv

    # Durchlaufen Sie alle Datensätze in der CSV-Datei.
    foreach ($employee in $employee_list) {

        # Überprüfen Sie, ob die Mitarbeiter-ID des aktuellen Datensatzes dem Wert des EmployeeID-Parameters entspricht.
        if ($employee.EmployeeID -eq $EmployeeID) {

            # Wenn die Mitarbeiter-ID gefunden wird, geben Sie den Datensatz auf der Konsole aus.
            Write-Host "$($employee.Name), whose Employee ID is $($employee.EmployeeID), was born on $($employee.Birthday)."
        }
    }
}

Nachdem der Funktionscode in die PowerShell-Sitzung importiert wurde, rufen Sie ihn durch Eingabe des Funktionsnamens wie folgt auf.

Find-Employee

Wenn die Funktion ohne Verwendung des EmployeeID-Parameters ausgeführt wird, wird nach dem Wert der EmployeeID für die Suche gefragt. Siehe das folgende Beispiel-Output.

Function to search a CSV file for a specific record

Oder die Funktion kann mit dem Wert des EmployeeID-Parameters zur Laufzeit ausgeführt werden, wie unten gezeigt.

Find-Employee -EmployeeID 'E-2023'

Speichernutzung von mehreren Servern abrufen

Eine häufige Routineaufgabe für Systemadministratoren besteht darin, die Speichernutzung mehrerer Server zu überwachen. Anstatt sich bei jedem Server anzumelden, um die Speichernutzung zu überprüfen, können Sie eine CSV-Liste erstellen, die Servernamen, Laufwerksbuchstaben und Schwellenwerte enthält. Anschließend können Sie mit PowerShell die CSV-Datei importieren und jede Zeile durchlaufen, um eine Abfrage auszuführen.

Um ein Skript zu erstellen, das den Festplattenspeicherplatz von entfernten Servern abruft, erstellen Sie zunächst die CSV-Liste mit den folgenden Überschriften:

  • servername – dies ist der Name des Servers, der abgefragt werden soll.
  • disk – dies ist der Buchstabe des Laufwerks, dessen Speichernutzung abgerufen werden soll.
  • threshold – dies definiert die Schwelle in GB. Wenn der freie Speicherplatz der Festplatte niedriger als dieser Wert ist, wird der Bericht einen Warnstatus anzeigen.

Das unten stehende Beispiel zeigt, dass vier Datensätze aufgelistet sind. Ihre CSV-Datei wird je nach Anzahl der zu lesenden Server oder Laufwerke unterschiedlich sein.

servername,disk,threshold
au-dc01,c,120
au-mail01,c,100
au-mail01,d,6
au-file01,c,120

Sobald die CSV-Datei abgeschlossen ist, speichern Sie die Datei als servers.csv. Dies dient als Eingabeliste, die vom PowerShell-Skript importiert wird.

Um ein Beispiel für das Abrufen der Speichernutzung zu geben, kopieren Sie den unten stehenden Code in Ihren Skript-Editor und speichern Sie ihn als diskReport.ps1. Das Skript muss im selben Speicherort wie der CSV-Pfad gespeichert werden.

$server_list = Import-Csv -Path .\servers.csv

foreach ($server in $server_list) {
    Get-WmiObject -Class Win32_logicaldisk -ComputerName ($server.servername) | `
        Where-Object { $_.DeviceID -match ($server.disk) } | `
        Select-Object `
    @{n = 'Server Name'; e = { $_.SystemName } }, `
    @{n = 'Disk Letter'; e = { $_.DeviceID } }, `
    @{n = 'Size (GB)'; e = { $_.Size / 1gb -as [int] } }, `
    @{n = 'Free (GB)'; e = { $_.FreeSpace / 1gb -as [int] } }, `
    @{n = 'Threshold (GB)'; e = { $server.Threshold } }, `
    @{n = 'Status'; e = {
            if (($_.FreeSpace / 1gb) -lt ($server.Threshold)) {
                return 'Warning'
            }
            else {
                return 'Normal'
            }
        }
    }
}

Das obige Skript führt nach der Ausführung die folgenden Aktionen aus.

  • Importiert die CSV-Datei mit dem Namen servers.csv und speichert sie in der Variable $server_list.
  • Durchläuft die Liste der Server, die in der Variable $server_list gespeichert sind.
  • In jeder Iteration der foreach-Schleife wird die aktuelle Zeile durch die Variable $server repräsentiert.
  • Ruft die Festplatteninformationen von den Servern mithilfe des Get-WmiObject-Cmdlets ab.
  • Nur relevante Eigenschaften anzeigen.
    Servername – Dies ist der Name des Systems, das abgefragt wird.
    Laufwerksbuchstabe – Der Buchstabe, der dem Laufwerk zugewiesen ist.
    Größe (GB) – Die Größe der Festplatte in GB.
    Frei (GB) – Die Größe des freien Speicherplatzes in GB.
    Schwellenwert (GB) – Der definierte Schwellenwert in GB.
    Status – Wenn der Wert von Frei (GB) niedriger ist als der Wert von Schwellenwert (GB), wird der Status ‚Warnung‘ zurückgegeben. Andernfalls wird der Status ‚Normal‘ sein.

Nachdem die Skriptdatei diskReport.ps1 gespeichert wurde, ist sie nun bereit, indem Sie ihren Namen in PowerShell aufrufen.

./diskReport.ps1

Nach der Ausführung zeigt der folgende Screenshot die Ausgabe des Skripts.

Disk space information gathered from multiple servers

Die Ausgabe kann auch in eine CSV-Datei exportiert werden. Der Export in eine CSV-Datei ist nützlich, wenn der Bericht geteilt werden muss, da die exportierte CSV-Datei per E-Mail versendet oder in einem Dateifreigabe- oder SharePoint-Website hochgeladen werden kann. Weitere Informationen zum Exportieren in CSV finden Sie unter Export-Csv: Der PowerShell-Weg, CSV-Dateien als erstklassige Bürger zu behandeln.

Erstellen mehrerer Active Directory-Benutzer

Zu diesem Zeitpunkt sollten Sie bereits eine solide Vorstellung davon haben, wie Sie Import-Csv und ForEach verwenden. Das nächste Beispiel geht einen Schritt weiter und fügt die Cmdlets New-ADUser und Get-ADUser hinzu.

Nehmen wir an, Sie haben eine CSV-Datei new_employees.csv erhalten, die die Liste der neuen Mitarbeiter von der Personalabteilung enthält. Jede Zeile in der CSV-Datei repräsentiert einen Benutzer, der eingestellt werden soll, und hat die folgenden Spalten: Vorname, Nachname, Abteilung, Bundesland, MitarbeiterID und Büro.

Der Benutzername wird aus dem ersten Buchstaben des Vornamens des Mitarbeiters abgeleitet, der mit dem Nachnamen verbunden ist (z.B. bparr für den Benutzer Bob Parr).

CSV file containing new employees information for on-boarding

Nachdem die CSV-Datei gespeichert wurde, verwendet das unten stehende Skript Import-Csv, um die CSV-Datei new_employees.csv zu lesen. Anschließend wird durch jede Zeile iteriert und die Werte an die entsprechenden Parameter von New-ADUser übergeben.

Import-Csv .\new_employees.csv | ForEach-Object {
    New-ADUser `
        -Name $($_.FirstName + " " + $_.LastName) `
        -GivenName $_.FirstName `
        -Surname $_.LastName `
        -Department $_.Department `
        -State $_.State `
        -EmployeeID $_.EmployeeID `
        -DisplayName $($_.FirstName + " " + $_.LastName) `
        -Office $_.Office `
        -UserPrincipalName $_.UserPrincipalName `
        -SamAccountName $_.SamAccountName `
        -AccountPassword $(ConvertTo-SecureString $_.Password -AsPlainText -Force) `
        -Enabled $True
}

Nach Ausführung des Skripts sollten die neuen Benutzer bereits im Active Directory vorhanden sein. Es ist jedoch eine gute Praxis, zu bestätigen, dass die Benutzerkonten tatsächlich erstellt wurden.

Mit derselben CSV-Datei new_employees.csv als Referenz wird das unten stehende Skript CSV importieren und für jede ADUser-Objekte abrufen, die mit denen in der Liste übereinstimmen.

Import-Csv .\new_employees.csv | ForEach-Object {
	Get-AdUser $_.SamAccountName
}

Hinzufügen einer Proxy-E-Mail-Adresse zum Office 365-Postfach

In der Verwaltung von Office 365-Postfächern ist es nicht ungewöhnlich, Anfragen zur Hinzufügung von Proxy-Adressen für mehrere Benutzer zu erhalten. In solchen Fällen erhält der Administrator in der Regel eine Liste der Benutzer und die hinzuzufügende E-Mail-Adresse, ähnlich wie im folgenden CSV-Beispiel.

The new_address.csv file contents

Hinweis: Bevor Sie Exchange Online-Cmdlets in PowerShell ausführen können, müssen Sie sich zuerst in der Exchange Online-Verwaltungsshell anmelden.

Mit Hilfe des Import-Csv-Befehls und einer ForEach-Schleife in einem PowerShell-Skript kann die Liste auf einmal verarbeitet werden. Das folgende Skript zeigt, wie es gemacht werden kann.

Das Skript importiert den Inhalt der Datei new_address.csv und speichert ihn in der Variablen $user_list. Anschließend durchläuft PowerShell mit der foreach()-Methode die gesamte Liste der Benutzer und fügt jeder Mailbox eine neue E-Mail-Adresse basierend auf den Werten username und email in jedem Datensatz hinzu.

$user_list = Import-Csv .\new_address.csv

$user_list.foreach(
    {
        Set-Mailbox -Identity $_.username -EmailAddresses @{add="$($_.email)"}
    }
)

Nachdem das Skript ausgeführt wurde, wird keine Ausgabe in der Konsole angezeigt. Keine Bildschirmausgabe bedeutet, dass die neuen E-Mail-Adressen erfolgreich hinzugefügt wurden. Aber wie können Sie sicherstellen, dass die E-Mail-Adressen hinzugefügt wurden?

Mit Hilfe derselben CSV-Datei new_address.csv als Referenz können Sie überprüfen, ob die neuen Adressen mit Import-Csv und ForEach hinzugefügt wurden.

Das folgende Skript importiert den Inhalt der Datei new_address.csv und speichert ihn in der Variablen $user_list. Anschließend durchläuft PowerShell mit der foreach()-Methode die gesamte Liste der Benutzer, um zu überprüfen, ob die neue E-Mail-Adresse in der Liste der Proxy-Adressen der Mailbox vorhanden ist. Wenn sie gefunden wird, wird der Status True zurückgegeben, andernfalls False.

$user_list = Import-Csv .\new_address.csv

$user_list.foreach(
    {
        $emailObj = (Get-Mailbox -Identity $_.username).EmailAddresses
        if ($emailObj -contains $_.email) {
            Write-Host "$($_.username) --> $($_.email) --> TRUE"
        }
        else {
            Write-Host "$($_.username) --> $($_.email) --> FALSE"
        }
    }
)

Wenn das Validierungsskript ausgeführt wird, sollte die Ausgabe wie im untenstehenden Screenshot aussehen. In der untenstehenden Ausgabe ist zu erkennen, dass der Status für alle TRUE ist, was bedeutet, dass die neuen E-Mail-Adressen erfolgreich zu jedem Postfach hinzugefügt wurden.

Running the new email address verification

Versenden des täglichen Wetterberichts an eine Mailingliste

In diesem Beispiel wird angenommen, dass Sie eine CSV-Datei mit einer Liste der E-Mail-Adressen der Abonnenten und ihrem Bereich oder ihrer Lage haben. Diese Abonnenten erwarten eine tägliche E-Mail mit dem Wetterbericht für den Tag, der spezifisch für ihren Standort ist. Schauen Sie sich die untenstehende Beispiel-CSV-Datei mit dem Dateinamen subscribers.csv an.

Weather forecast subscribers list

Die untenstehende CSV-Datei enthält nur zwei Abonnenten. Einer in Los Angeles und einer in Manila.

Ziel ist es, ein Skript zu erstellen, das die folgenden Aktionen ausführt:

  • Importieren Sie die E-Mail- und Bereichsinformationen aus der Datei subscribers.csv
  • Für jeden Abonnenten:
    – Laden Sie das Wettervorhersagebild basierend auf dem Bereich des Abonnenten von https://wttr.in/ herunter
    – Senden Sie das Wettervorhersagebild als E-Mail an die E-Mail-Adresse des Abonnenten.

Das untenstehende Skript führt die oben aufgeführten Aktionen aus. Sie müssen nur die ersten drei Variablen – $senderAddress, $smtpServer und $smtpPort – ändern. Kopieren Sie dann diesen Code und speichern Sie ihn als Send-WeatherInfo.ps1. Lesen Sie die Kommentare über jedem Abschnitt des Skripts, um mehr darüber zu erfahren, was der Code tut.

# Hier SMTP-Einstellungen einfügen
$senderAddress = '<SENDER EMAIL ADDRESS HERE'
$smtpServer = '<SMTP RELAY SERVER HERE>'
$smtpPort = 25
# Hier SMTP-Einstellungen einfügen

# Importiere die E-Mail-Liste der Abonnenten
$subscriber_list = Import-Csv .\subscribers.csv

# Hole Wettervorhersage und sende E-Mail
$subscriber_list.foreach(
    {
				
        # Baue URL für Wetterinformationen basierend auf dem Gebiet
        $uri = ('<https://wttr.in/>' + $_.Area + '_u1F.png')
        # Hole das Wettervorhersagebild des Gebiets. Speichere das Bild als <GEBIET>.png
        $imageFile = (((Resolve-Path .\).Path) + "$($_.Area).png")
        Start-BitsTransfer $uri -Destination $imageFile

        # Erstelle Anhangsobjekt
        $attachment = New-Object System.Net.Mail.Attachment -ArgumentList $imageFile
        $attachment.ContentDisposition.Inline = $true
        $attachment.ContentDisposition.DispositionType = "Inline"
        $attachment.ContentType.MediaType = "image/png"
        $attachment.ContentId = "weatherImage"

        # Verfasse Nachricht
        $emailMessage = New-Object System.Net.Mail.MailMessage
        $emailMessage.From = $senderAddress
        $emailMessage.To.Add($_.Email)
        $emailMessage.Subject = ('Weather Forecast - ' + $_.Area)
        $emailMessage.IsBodyHtml = $true
        $emailMessage.Body = '<img src="cid:weatherImage">'
        $emailMessage.Attachments.Add($attachment)

        # Sende Nachricht
        Write-Output "Sending Weather Info to $($_.Email)"
				$smtp = New-Object Net.Mail.SmtpClient($smtpServer, $smtpPort)
        $smtp.Send($emailMessage)

        # Objekte freigeben
        $attachment.Dispose()
        $emailMessage.Dispose()
    }
)

Wenn das Skript ausgeführt wird, wird eine E-Mail an jeden Abonnenten gesendet, ähnlich wie in der Beispielscreenshot unten.

Weather forecast for Manila sent as an email to the subscriber
Weather forecast for Los Angeles sent as an email to the subscriber

Zusammenfassung

Es gibt keine Begrenzung für die Aufgaben, bei denen das Import-Csv und die ForEach-Schleife angewendet werden können. Solange die Aufgabe eine Liste mit abgegrenzten Spalten umfasst, kannst du sicher in diese leistungsstarke Kombination eintauchen.

In diesem Artikel hast du gelernt, wie eine CSV-Datei einer Datenbank ähnelt. Du hast auch gelernt, wie du Import-Csv zum Importieren von Daten verwendest und wie du auf die Werte während der ForEach-Schleifeniteration verweist.

I hope that with the many examples provided in this article, you now understand more of the Import-Csv and ForEach. And, that you would be able to use the knowledge you gained in this article in your administration and automation tasks.

Weiterführende Informationen

Source:
https://adamtheautomator.com/import-csv-and-the-foreach-loop/