Comment exporter des données au format CSV avec PowerShell ?
Sommaire
I. Présentation
Dans ce tutoriel, 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 volet sur la gestion des fichiers CSV avec PowerShell était une évidence pour traiter le sujet entièrement.
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
Commençons par lister les services :
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
A ce stade, dans la console nous avons la sortie que nous aimerions avoir dans le CSV : une liste avec trois colonnes. 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 l'on ne fait 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 l'on va venir préciser à la suite de notre commande avec le pipe "|". Nous allons spécifier deux paramètres : le chemin vers le fichier CSV de sortie (-Path) et le délimiteur que l'on souhaite (-Delimiter).
Ce qui donne :
Get-Service | Select-Object Name, DisplayName, Status | Export-CSV -Path "C:\TEMP\services.csv" -Delimiter ";"
Si vous ouvrez le fichier "services.csv", vous allez voir qu'il y a une première ligne 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
Note : 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.
J'obtiens donc le fichier CSV suivant :
Quelques petites astuces et précisions au sujet d'Export-CSV....
Pour ajouter du contenu à un fichier CSV déjà existant, il faut spécifier l'option -Append. Sinon, le fichier est é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. Exemple pour spécifier la colonne 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, il faut intervenir au sein de la commande "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). On va remplacer :
DisplayName
Par :
@{ expression={$_.DisplayName}; label='NomAffichage' }
La colonne de notre CSV sera nommée "NomAffichage", ce qui est plus sympa !
Si l'on renomme 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.
III. Construire son propre fichier CSV
Pour finir ce tutoriel, je vous propose une autre approche : la création de son propre fichier 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 créer un rapport.
On pourrait créer un objet, venir l'alimenter au fur et à mesure et l'export au format CSV à la fin, mais on peut aussi écrire dans un fichier. Tout simplement.
Commençons par créer le fichier CSV vierge, puis à lui ajouter nos-entêtes :
New-Item -ItemType File -Path "C:\TEMP\Log.csv"
Voici la commande pour 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 l'on ouvre le fichier avec un éditeur de texte (ou même avec Excel, c'est l'intérêt), on obtient :
PS : ce fichier CSV peut également être importé avec Import-CSV sans aucun problème ! 😉
L’option -UseQuotes n’est pas disponible dans la version 5 de PowerShell.
Elle est disponible sur la version 7. Mais cela nécessite l’installation de VSCode.
C’est pas bien difficile, mais cela peut aider de le savoir.