Comment exporter des données au format CSV avec PowerShell ?
Sommaire
I. Présentation
Dans ce chapitre, nous allons voir comment exporter des données au format CSV en PowerShell, à l'aide de la commande "Export-CSV".
Après avoir vu comment importer des données à partir d'un fichier CSV avec PowerShell, ce second chapitre va évoquer l'utilisation du cmdlet "Export-CSV" pour exporter des objets dans un fichier CSV avec PowerShell.
Pour cet exemple, nous allons voir comment exporter la liste des services Windows au format CSV, en récupérant certaines propriétés (nom technique, nom d'affichage et l'état du service).
II. Exporter des données dans un CSV avec Export-CSV
Nous allons commencer par lister les services avec un cmdlet que vous connaissez, car nous l'avons utilisé à plusieurs reprises :
Get-Service
Ensuite, nous allons sélectionner les propriétés que l'on souhaite exporter : Name, DisplayName et Status.
Ce qui donne :
Get-Service | Select-Object DisplayName, Name, Status
À ce stade, dans la console, nous avons la sortie que nous aimerions avoir dans le CSV : une liste avec trois colonnes, grâce aux trois propriétés sélectionnées. Quand la sortie dans la console correspond à ce que vous souhaitez avoir dans le CSV, il ne reste plus qu'à faire l'export au format CSV.
Note : si nous ne faisons pas la sélection des propriétés avec Select-Object, l'export CSV va prendre toutes les propriétés retournées par Get-Service.
Cet export au format CSV s'effectue avec "Export-CSV" que nous allons préciser à la suite de notre commande, derrière le pipeline. Nous allons spécifier deux paramètres :
- -Path : le chemin vers le fichier CSV de sortie
- -Delimiter : le caractère à utiliser en tant que délimiteur
Ce qui donne :
Get-Service | Select-Object Name, DisplayName, Status | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";"
Si nous ouvrons le fichier "services.csv", nous pouvons voir que la première ligne est assez surprenante :
#TYPE Selected.System.ServiceProcess.ServiceController
Cela donne des informations sur le type de données. Cependant, ce n'est pas pour nous arranger, car la première ligne doit correspondre à nos en-têtes de colonnes... Fort heureusement, il y a un paramètre qui permet de supprimer cette ligne : "-NoTypeInformation".
Il suffit de l'ajouter et cette ligne sera un lointain souvenir !
Get-Service | Select-Object Name, DisplayName, Status | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";" -NoTypeInformation
Remarque : cette ligne est intégrée au fichier CSV seulement lors de l'utilisation de Windows PowerShell. Si vous utilisez PowerShell Core (PowerShell 7+), cette ligne n'apparaîtra pas et l'option n'existe même pas. Par contre, il y a une option (-IncludeTypeInformation) qui permet d'ajouter l'information si besoin.
Au final, voici un aperçu du fichier CSV obtenu :
III. Astuces pour l'utilisation d'Export-CSV
Pour ajouter du contenu à un fichier CSV déjà existant, nous devons spécifier le paramètre "-Append". Sinon, le fichier sera écrasé à chaque fois, même s'il existe déjà.
$ListeDesServices = Get-Service | Select-Object Name, DisplayName, Status
$ListeDesServices | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";" -Append
Comme lors d'un import d'un fichier CSV, le paramètre "-Encoding" sert à spécifier l'encodage pour notre fichier de sortie.
Sur les versions plus récentes de PowerShell, notamment PowerShell Core 7, il y a une option nommée "-UseQuotes" qui permet de préciser si l'on doit encadrer les valeurs par des guillemets ou non. Utile si vous avez des chaînes de caractères avec des espaces, mais pas spécialement pour des chiffres. Ce paramètre peut prendre plusieurs valeurs : Always (toujours), AsNeeded (si besoin), Never (jamais).
Par exemple :
$ListeDesServices = Get-Service | Select-Object Name, DisplayName, Status
$ListeDesServices | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";" -UseQuotes Always
Un peu dans le même esprit, le paramètre "-QuoteFields" sert à spécifier les colonnes pour lesquelles il faut encadrer les valeurs avec des guillemets. Par exemple, voici la syntaxe à utiliser pour spécifier la propriété "DisplayName" :
$ListeDesServices = Get-Service | Select-Object Name, DisplayName, Status $ListeDesServices | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";" -QuoteFields DisplayName
Pour finir, nous allons voir comment modifier le nom des colonnes de notre fichier CSV au moment de l'export. Pour cela, nous devons utiliser le cmdlet "Select-Object".
Au lieu de préciser tout simplement "DisplayName" pour sélectionner cette propriété, nous allons créer une propriété calculée afin de changer le nom (label). Nous allons remplacer ce code :
DisplayName
Par celui-ci :
@{ expression={$_.DisplayName}; label='NomAffichage' }
La colonne de notre CSV sera nommée "NomAffichage", ce qui est plus sympa !
Si nous renommons nos trois colonnes avec un nom personnalisé, cela donne :
Get-Service | Select-Object @{ expression={$_.Name}; label='Nom' },@{ expression={$_.DisplayName}; label='NomAffichage' },@{ expression={$_.Status}; label='Statut' } | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";"
Voilà, le fichier CSV sera le même précédemment, à la différence que nos en-têtes auront des noms en français.
IV. Construire un fichier CSV avec Add-Content
Pour terminer, nous allons évoquer une autre approche pour créer notre propre fichier CSV en partant de zéro, sans utiliser "Export-CSV". Cela m'est déjà arrivé d'utiliser cette méthode pour générer un fichier de log formaté avec des colonnes, ou pour créer un rapport.
Nous pourrions créer un objet, venir l'alimenter au fur et à mesure et l'exporter au format CSV à la fin, mais nous pouvons aussi écrire dans un fichier. Tout simplement.
Commençons par créer le fichier CSV vierge, puis à lui ajouter nos en-têtes c'est-à-dire nos différents champs :
New-Item -ItemType File -Path "C:\TEMP\Log.csv"
À l'aide du cmdlet "Add-Content", dont l'objectif est d'ajouter du contenu à un fichier, nous allons ajouter la première ligne correspondante aux en-têtes : Date, Type, Message. Ce sera la base de notre fichier de log.
Add-Content -Path "C:\TEMP\Log.csv" -Value "Date;Type;Message"
Ensuite, quand vous avez besoin d'ajouter une ligne de log dans le fichier, il suffit d'ajouter du contenu dans le fichier en respectant les trois colonnes. Dans l'exemple ci-dessous, la colonne "Date" prendra pour valeur la date et l'heure actuellement, automatiquement.
Add-Content -Path "C:\TEMP\Log.csv" -Value "$(Get-Date -Format yyyyMMdd_HHmm);Erreur;Voici le détail de l'erreur !"
Si nous ouvrons le fichier avec un éditeur de texte (ou même avec Excel, c'est l'intérêt), nous obtenons :
Par la suite, ce fichier CSV pourra être importé avec le cmdlet Import-CSV si nous avons besoin !