Traitement des données CSV avec Import-Csv et boucle ForEach en PowerShell

Avez-vous déjà dû effectuer la même tâche plusieurs fois ? Par exemple, créer plusieurs utilisateurs Active Directory un par un en utilisant l’interface graphique ? Ou encore, vous connecter à un serveur pour supprimer d’anciens journaux de certains dossiers sélectionnés ? Si votre réponse est oui, sachez que vous n’êtes pas seul. Il est temps de maîtriser la commande PowerShell Import-Csv et la boucle foreach.

Il n’y a rien de mal à effectuer des tâches manuelles ; cela est parfois nécessaire. Mais quand il s’agit de lire et de traiter des fichiers CSV, la commande PowerShell Import-Csv et la boucle ForEach peuvent être utiles.

La commande PowerShell Import-Csv est un excellent moyen de lire des données à partir d’une source tabulée telle qu’un fichier CSV. Vous pouvez utiliser la boucle ForEach pour itérer sur chaque ligne des données CSV.

Dans cet article, vous apprendrez à utiliser cette combinaison puissante pour automatiser des tâches en masse, ennuyeuses et répétitives.

Si vous êtes novice avec la commande Import-Csv et la boucle ForEach, ou si vous souhaitez simplement vous rafraîchir la mémoire sur ce que vous savez déjà, vous pouvez consulter ces liens pour en savoir plus.

Gestion des fichiers CSV avec Import-Csv (boucle foreach) en PowerShell

Retour aux bases : la boucle foreach en PowerShell

Prérequis

Cet article contient plusieurs exemples et démonstrations. Pour suivre, vous aurez besoin de quelques éléments préalables.

  • A script editor such as Visual Studio Code, Atom, or Notepad++. Use whichever one you’re comfortable with.
  • Windows PowerShell 5.1 ou PowerShell Core 6+
  • Accès à Exchange Online (facultatif si vous suivez l’exemple pratique lié à Exchange Online).

Mise en pratique de l’importation de CSV et de la boucle ForEach

Dans les sections suivantes, vous trouverez plusieurs exemples d’utilisation de la cmdlet Import-Csv et de la boucle ForEach que vous pouvez rencontrer dans des scénarios réels. Bien que ces exemples d’importation de CSV foreach en PowerShell soient spécifiques à chaque objectif, il est crucial de comprendre que le concept et la technique utilisés sont les mêmes.

Lecture et affichage des enregistrements d’un fichier CSV

La manière la plus basique d’utiliser Import-Csv et la boucle ForEach consiste à lire les enregistrements d’un fichier et à les afficher dans la console. La structure d’un fichier CSV est similaire à celle d’une base de données. Il possède des en-têtes de colonnes, et chaque ligne est considérée comme un enregistrement.

Par exemple, voici le contenu du fichier appelé employee.csv, qui comprend trois colonnes – EmployeeID, Nom et Date de naissance, et quatre enregistrements.

CSV containing employee records

Le code ci-dessous importe le contenu du fichier employee.csv puis envoie les données importées à la cmdlet ForEach-Object. Ensuite, ForEach-Object parcourra chaque enregistrement du CSV importé pour afficher les valeurs concaténées dans la console. Copiez le code ci-dessous et enregistrez-le sous le nom de list-employee.ps1.

Note: Le type de boucle ForEach utilisé dans cet exemple ci-dessous est la cmdlet ForEach-Object. Reportez-vous à la section « La cmdlet ForEach-Object » dans cet article.

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

Une fois que le script est enregistré, exécutez-le en appelant son nom de fichier dans PowerShell. Lorsque le script est exécuté, vous devriez voir une sortie similaire à la capture d’écran ci-dessous.

Imported CSV records displayed in the console

Recherche et affichage des enregistrements à partir d’un fichier CSV

Dans l’exemple précédent, vous avez appris comment lire et afficher tous les enregistrements à partir d’un fichier CSV. Dans cet exemple, le même fichier CSV employee.csv sera utilisé, mais cette fois, vous allez créer une fonction PowerShell pour rechercher un EmployeeID dans le CSV.

Le code ci-dessous est une fonction PowerShell appelée Find-Employee qui a un seul paramètre. Le nom du paramètre est EmployeeID et il accepte une valeur d’ID d’employé à rechercher dans le CSV.

Avant que cette fonction puisse être utilisée, elle doit être importée dans votre session PowerShell. Il existe deux façons d’importer la fonction Find-Employee dans la mémoire:

  1. Copier et coller le code ci-dessous dans PowerShell.
  2. Enregistrer le script sous le nom Find-Employee.ps1 et l’importer en utilisant la technique du dot-sourcing.

Note: Le type de boucle ForEach utilisée dans cet exemple ci-dessous est la déclaration ForEach. Veuillez vous reporter à la section « La déclaration foreach » dans cet article.

Function Find-Employee {
    param (
        # Le paramètre accepte l'ID de l'employé à rechercher.
        [Parameter(Mandatory)]
        $EmployeeID
    )

    # Importez le contenu du fichier employee.csv et stockez-le dans la variable $employee_list.
    $employee_list = Import-Csv .\employee.csv

    # Parcourez tous les enregistrements du CSV
    foreach ($employee in $employee_list) {

        # Vérifiez si l'ID de l'employé de l'enregistrement en cours est égal à la valeur du paramètre EmployeeID.
        if ($employee.EmployeeID -eq $EmployeeID) {

            # Si l'EmployeeID est trouvé, afficher l'enregistrement dans la console.
            Write-Host "$($employee.Name), whose Employee ID is $($employee.EmployeeID), was born on $($employee.Birthday)."
        }
    }
}

Une fois que le code de la fonction est importé dans la session PowerShell, appelez-le en tapant le nom de la fonction comme ci-dessous.

Find-Employee

Lorsque la fonction est exécutée sans utiliser le paramètre EmployeeID, elle demandera la valeur de EmployeeID à rechercher. Voir la sortie d’exemple ci-dessous.

Function to search a CSV file for a specific record

Ou, la fonction peut être exécutée avec la valeur du paramètre EmployeeID spécifiée lors de l’exécution, comme indiqué ci-dessous.

Find-Employee -EmployeeID 'E-2023'

Obtenir l’utilisation de l’espace disque à partir de plusieurs serveurs

Une tâche courante parmi les administrateurs système est de surveiller l’utilisation de l’espace disque de plusieurs serveurs. Au lieu de vous connecter à chaque serveur pour vérifier l’utilisation de l’espace disque, vous pouvez créer une liste CSV contenant les noms des serveurs, les lettres de lecteur et les seuils. Ensuite, à l’aide de PowerShell, importez le fichier CSV et parcourez chaque ligne pour exécuter une requête.

Pour créer un script qui obtient l’utilisation de l’espace disque à partir de serveurs distants, commencez par créer une liste CSV avec les en-têtes suivants :

  • nom du serveur – c’est le nom du serveur à interroger.
  • disque – c’est la lettre du lecteur dont l’utilisation de l’espace sera récupérée.
  • seuil – cela définit le seuil en Go. Si l’espace libre du disque est inférieur à cette valeur, le rapport affichera un statut d’avertissement.

L’exemple ci-dessous montre qu’il y a quatre enregistrements répertoriés. Votre fichier CSV sera différent en fonction du nombre de serveurs ou de disques à lire.

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

Une fois que le CSV est finalisé, enregistrez le fichier sous le nom de servers.csv. Cela servira de liste d’entrée qui sera importée par le script PowerShell.

Pour donner un exemple d’obtention de l’utilisation de l’espace disque, copiez le code ci-dessous dans votre éditeur de script et enregistrez-le sous le nom de diskReport.ps1. Le script doit être enregistré dans le même emplacement que le chemin du CSV.

$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'
            }
        }
    }
}

Le script ci-dessus effectue les actions suivantes une fois qu’il est exécuté.

  • Importe le fichier csv nommé servers.csv et le stocke dans la variable $server_list.
  • Boucle à travers la liste des serveurs stockés dans la variable $server_list.
  • A chaque itération de la boucle foreach, la ligne actuelle est représentée par la variable $server.
  • Obtient les informations sur le disque des serveurs en utilisant la cmdlet Get-WmiObject.
  • Sélectionnez uniquement les propriétés pertinentes à afficher.
    Nom du serveur – Il s’agit du nom du système interrogé.
    Lettre du disque – La lettre attribuée au lecteur.
    Taille (Go) – La taille du disque en Go
    Libre (Go) – La taille de l’espace libre en Go
    Seuil (Go) – Le seuil défini en Go
    Statut – Si la valeur de Libre (Go) est inférieure à la valeur de Seuil (Go), le statut renvoyé est « Avertissement ». Sinon, le statut sera « Normal »

Après avoir enregistré le fichier de script diskReport.ps1, il est maintenant prêt à être exécuté en appelant son nom dans PowerShell.

./diskReport.ps1

Une fois exécuté, la capture d’écran ci-dessous montre la sortie du script.

Disk space information gathered from multiple servers

La sortie peut également être exportée au format CSV. L’exportation au format CSV est utile lorsque le rapport doit être partagé car le fichier CSV exporté peut être envoyé par e-mail ou téléchargé vers un partage de fichiers ou un site SharePoint. N’oubliez pas de consulter Export-Csv : La façon PowerShell de traiter les fichiers CSV comme des citoyens de première classe si vous souhaitez plus d’informations sur l’exportation vers CSV.

Création de plusieurs utilisateurs dans Active Directory

À ce stade, vous avez déjà une bonne idée de l’utilisation de Import-Csv et ForEach. L’exemple suivant va un peu plus loin en ajoutant les cmdlets New-ADUser et Get-ADUser dans le mélange.

Supposons que vous ayez reçu un fichier CSV new_employees.csv contenant la liste des nouveaux employés du département des ressources humaines. Chaque ligne du fichier CSV représente un utilisateur à intégrer et comporte les colonnes suivantes : Prénom, Nom de famille, Département, État, ID de l’employé et Bureau.

Le nom d’utilisateur doit être dérivé de la première lettre du prénom de l’employé concaténée avec le nom de famille (par exemple, bparr pour l’utilisateur Bob Parr).

CSV file containing new employees information for on-boarding

Une fois le fichier CSV enregistré, le script ci-dessous utilise Import-Csv pour lire le fichier CSV new_employees.csv. Ensuite, il itère sur chaque ligne, en passant les valeurs aux paramètres appropriés de New-ADUser.

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
}

Après l’exécution du script, les nouveaux utilisateurs devraient déjà exister dans Active Directory. Cependant, il est recommandé de confirmer que les comptes d’utilisateur ont réellement été créés.

En utilisant le même fichier CSV new_employees.csv comme référence, le script ci-dessous exécutera l’import CSV et une boucle pour obtenir les objets ADUser correspondant à ceux de la liste.

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

Ajout d’une adresse de messagerie proxy à une boîte aux lettres Office 365

Dans la gestion des boîtes aux lettres Office 365, il n’est pas rare de recevoir des demandes d’ajout d’adresses proxy pour plusieurs utilisateurs. Généralement, dans ce type de demande, l’administrateur reçoit une liste d’utilisateurs et l’adresse e-mail à ajouter, similaire à l’exemple CSV ci-dessous.

The new_address.csv file contents

Note : Avant de pouvoir exécuter les cmdlets Exchange Online dans PowerShell, vous devez d’abord vous connecter à l’interpréteur de commandes Gestion Exchange en ligne.

En utilisant les commandes Import-Csv et ForEach dans un script PowerShell, la liste peut être traitée en une seule fois. Le script ci-dessous montre comment cela peut être fait.

Le script ci-dessous importe le contenu du fichier new_address.csv et le stocke dans la variable $user_list. Ensuite, en utilisant la méthode foreach(), PowerShell parcourt toute la liste des utilisateurs et utilise les valeurs username et email de chaque enregistrement pour ajouter une nouvelle adresse e-mail à chaque boîte aux lettres.

$user_list = Import-Csv .\new_address.csv

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

Une fois que le script est exécuté, aucun résultat n’est affiché dans la console. L’absence de sortie à l’écran signifie que la nouvelle adresse e-mail a été ajoutée avec succès. Mais comment pouvez-vous vous assurer que les adresses e-mail ont été ajoutées?

En utilisant le même fichier CSV new_address.csv comme référence, il est possible de vérifier si les nouvelles adresses ont été ajoutées en utilisant les commandes Import-Csv et ForEach.

Le script ci-dessous importe le contenu du fichier new_address.csv et le stocke dans la variable $user_list. Ensuite, en utilisant la méthode foreach(), PowerShell parcourt toute la liste des utilisateurs pour vérifier si la nouvelle adresse e-mail existe dans la liste des adresses de proxy de la boîte aux lettres. Si elle est trouvée, le statut renverra True; sinon, le résultat sera 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"
        }
    }
)

Lorsque le script de validation s’exécute, la sortie devrait ressembler à celle indiquée dans la capture d’écran ci-dessous. Vous remarquerez dans la sortie ci-dessous que le statut est tout TRUE, ce qui signifie que les nouvelles adresses e-mail ont été ajoutées à chaque boîte aux lettres avec succès.

Running the new email address verification

Envoi des prévisions météorologiques quotidiennes à une liste de diffusion

Dans cet exemple, on suppose que vous disposez d’un fichier CSV contenant une liste des adresses e-mail des abonnés et de leur zone ou emplacement. Ces abonnés s’attendent à recevoir un e-mail quotidien contenant les prévisions météorologiques spécifiques à leur emplacement. Regardez le CSV d’exemple ci-dessous avec le nom de fichier subscribers.csv.

Weather forecast subscribers list

Le CSV ci-dessous ne contient que deux abonnés. Un à Los Angeles et un à Manila.

L’objectif est de créer un script qui effectuera les actions suivantes:

  • Importer les informations d’e-mail et de zone à partir du fichier subscribers.csv
  • Pour chaque abonné:
    – Télécharger l’image des prévisions météorologiques en fonction de la zone de l’abonné depuis https://wttr.in/
    – Envoyer l’image des prévisions météorologiques par e-mail à l’adresse e-mail de l’abonné.

Le script ci-dessous effectue les actions énumérées ci-dessus. Vous devez uniquement modifier les trois premières variables – $senderAddress, $smtpServer et $smtpPort. Ensuite, copiez ce code et enregistrez-le sous le nom de Send-WeatherInfo.ps1. Consultez les commentaires au-dessus de chaque section du script pour en savoir plus sur ce que fait le code.

# Début des paramètres SMTP ici
$senderAddress = '<SENDER EMAIL ADDRESS HERE'
$smtpServer = '<SMTP RELAY SERVER HERE>'
$smtpPort = 25
# Début des paramètres SMTP ici

# Importez la liste des adresses e-mail des abonnés
$subscriber_list = Import-Csv .\subscribers.csv

# Obtenir les prévisions météorologiques et envoyer un e-mail
$subscriber_list.foreach(
    {
				
        # Construire l'URL des informations météorologiques en fonction de la zone
        $uri = ('<https://wttr.in/>' + $_.Area + '_u1F.png')
        # Obtenir l'image des prévisions météorologiques de la zone. Enregistrer l'image sous <AREA>.png
        $imageFile = (((Resolve-Path .\).Path) + "$($_.Area).png")
        Start-BitsTransfer $uri -Destination $imageFile

        # Créer un objet de pièce jointe
        $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"

        # Composer le message
        $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)

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

        # Libérer les objets
        $attachment.Dispose()
        $emailMessage.Dispose()
    }
)

Une fois le script exécuté, un e-mail sera envoyé à chaque abonné, similaire à la capture d’écran d’e-mail ci-dessous.

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

Résumé

Il n’y a pas de limite aux tâches où les commandes Import-Csv et la boucle ForEach peuvent être appliquées. Tant que la tâche implique une liste avec des colonnes délimitées, vous êtes sûr de pouvoir utiliser cette combinaison puissante.

Dans cet article, vous avez appris comment un fichier CSV est similaire à une base de données. Vous avez également appris à utiliser Import-Csv pour importer des données et comment référencer les valeurs pendant l’itération de la boucle ForEach.

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.

Lecture complémentaire

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