22/10/2024

PowerShell

Get-Content : comment lire le contenu d’un fichier en PowerShell ?

I. Présentation

Le cmdlet Get-Content fait partie des commandes incontournables lorsque l'on s'intéresse au scripting PowerShell. Il va permettre de lire le contenu d'un fichier en PowerShell, ce qui est une action très courante. En plus de lire les données, on va pouvoir importer les données dans une variable pour les exploiter dans le script PowerShell. On peut utiliser Get-Content pour récupérer le contenu d'un fichier de log, par exemple.

Nous verrons que Get-Content est un cmdlet puissant qui est capable de faire plus que simplement récupérer le contenu d'un fichier intégralement, d'où l'intérêt de lui dédier un article complet. Ce cmdlet fonctionne sous Windows Powershell 5.1 et PowerShell, notamment dans la dernière version à ce jour : PowerShell 7.1.1.

? Tutoriel disponible au format vidéo :

II. Lire simplement le contenu d'un fichier

Pour commencer, on va simplement lire le contenu d'un fichier texte qui contiendra une liste de valeurs. Pour suivre ce tutoriel, je vous invite à créer un fichier nommé "Pays.txt" et stocké dans "C:\TEMP". Ce fichier doit avoir le contenu suivant :

France
Costa Rica
Belgique
Suisse
Espagne
Colombie
Canada
Brésil
Islande
Nicaragua

Pour lire et afficher dans la console le contenu de ce fichier, la commande est super simple puisqu'il suffit de préciser le nom du fichier (ou le chemin complet s'il n'est pas dans le répertoire courant) :

Get-Content "C:\TEMP\Pays.txt"

Get-Content

Le paramètre -Path sera utilisé de manière implicite pour cette valeur. Si l'on écrit la commande ci-dessous, cela revient au même.

Get-Content -Path "C:\TEMP\Pays.txt"

Afficher le contenu dans la console ne donne pas grand-chose. C'est plus intéressant quand on va stocker le contenu du fichier dans une variable dans le but de l'exploiter. Il suffit de créer une variable, par exemple $Pays, et de lui attribuer le contenu du fichier comme valeur :

$Pays = Get-Content "C:\TEMP\Pays.txt"

Par curiosité, on peut regarder le type de la variable $Pays après lui avoir attribué une valeur :

$Pays.GetType()

On peut voir que l'on obtient deux informations pertinentes : "Object[]" et "System.Array". Nous avons affaire à un objet sous la forme d'un tableau de valeurs ; c'est intéressant ! ?

Pour compter le nombre d'éléments dans ce fichier texte, on peut le faire de deux façons différentes :

$Pays.Count
($Pays | Measure-Object).Count

Nous avons 10 éléments, puisqu'il s'agit d'un tableau la première valeur correspond à l'index 0 et la dernière à l'index 9 (puisque l'on a seulement 10 éléments). Ainsi, la valeur à l'index 0 sera "France" et celle à l'index 9 sera Nicaragua.

Si l'on veut consulter la valeur située en index 0, c'est-à-dire la première valeur, c'est tout simple :

$Pays[0]

Ou si vous préférez, cela revient à faire :

(Get-Content "C:\TEMP\Pays.txt")[0]

Dans le même esprit, pour récupérer la dernière valeur sans connaître le numéro d'index exact, il y a une astuce ! Il suffit d'utiliser "-1" comme numéro pour l'index :

(Get-Content "C:\TEMP\Pays.txt")[-1]

Au lieu de récupérer le contenu du fichier sous la forme d'un tableau, on peut le récupérer comme une seule chaîne de caractères. Il suffit d'ajouter le paramètre -Raw à la commande :

Get-Content -Path "C:\TEMP\Pays.txt" -Raw

Passons à la suite avec quelques exemples pratiques.

III. Le tail de Linux à la mode PowerShell

Sous Linux, il est très fréquent d'utiliser la commande tail pour afficher les dernières lignes d'un fichier. Bien souvent, je l'utilise pour consulter un fichier de log, d'autant plus que la sortie est dynamique : si des lignes sont ajoutées au fichier, elles s'afficheront dans la console au fur et à mesure.

C'est très pratique et c'est possible de faire la même chose en PowerShell, à l'aide de Get-Content et d'une option qui se nomme... -Tail et d'une deuxième option -Wait ! ?

Sans l'option -Wait, on peut récupérer les X dernières lignes d'un fichier en utilisant -Tail tout seul. Par exemple, pour récupérer les 5 dernières lignes de notre fichier Pays.txt :

Get-Content "C:\TEMP\Pays.txt" -Tail 5

Maintenant, si l'on veut afficher les 5 dernières lignes et attendre pour récupérer les futures lignes ajoutées au fichier, on va utiliser cette syntaxe :

Get-Content "C:\TEMP\Pays.txt" -Tail 5 -Wait

Pour faire le test, exécutez la commande ci-dessus puis modifiez le fichier "Pays.txt" pour ajouter une ligne : vous verrez qu'elle s'affiche quasiment en temps réel dans la console PowerShell où la commande tourne ?.

En fait, grâce à la commande -Wait, Get-Content maintient le fichier ouvert et vérifie chaque seconde s'il y a du nouveau contenu à afficher. Pour terminer l'exécution de la commande, c'est tout simple, il suffit d'effectuer un "CTRL + C".

Il est à noter que vous pouvez utiliser l'option -Wait seule : dans ce cas, le fichier va s'afficher en intégralité dans la console et ensuite il va rester en attente.

Get-Content "C:\TEMP\Pays.txt" -Wait

IV. Récupérer les X premières lignes d'un fichier

Dans le même esprit, on peut récupérer les premières lignes d'un fichier. Dans ce cas, on ne va pas utiliser -Tail mais plutôt -TotalCount à la place. Là encore, il faut spécifier le nombre de lignes à afficher.

Get-Content "C:\TEMP\Pays.txt" -TotalCount 5

Par contre, et c'est logique, l'option -Wait n'a pas d'utilité avec l'option -TotalCount.

V. NTFS : consulter un stream secret dans un fichier

Le système de fichiers NTFS a la particularité d'avoir différents "stream" dans lequel stocker les données. Lorsque l'on écrit des données dans un fichier, elles sont stockées dans le flux $DATA. Ainsi, lorsque l'on consulte le fichier, on va lire le contenu de ce flux de données.

D'ailleurs, on peut voir que notre fichier "Pays.txt" dispose bien de ce stream grâce à la commande Get-Item :

Get-Item "C:\TEMP\Pays.txt" -Stream *

On remarque également que la console retourne seulement ce flux de données.

Là où c'est cool, c'est que l'on peut créer son propre stream pour cacher des données à l'intérieur ! ?

Il suffit d'ajouter des données à notre fichier "Pays.txt" en spécifiant le stream dans lequel envoyer les données. Par exemple, nous allons créer le stream "Creds" avec la valeur "MotDePasse".

Add-Content -Path "C:\TEMP\Pays.txt" -Stream Creds -Value "MotDePasse"

Maintenant, si on affiche à nouveau la liste des streams de notre fichier, on obtient une nouvelle entrée :

Si l'on s'amuse à afficher le contenu de notre fichier, on verra que la valeur "MotDePasse" que je viens d'ajouter au fichier ne ressort pas.

Get-Content "C:\TEMP\Pays.txt"

D'ailleurs, pour consulter le flux par défaut, on peut préciser son nom à la suite du paramètre -Stream de Get-Content (attention à la syntaxe) :

Get-Content "C:\TEMP\Pays.txt" -Stream ':$DATA'

Si l'on veut afficher le contenu du stream "Creds" que l'on a créé précédemment, il suffit de le dire :

Get-Content "C:\TEMP\Pays.txt" -Stream Creds

La commande va retourner une seule valeur : MotDePasse

La preuve en image ci-dessous :

C'est à connaître, mais il ne faut pas non plus se dire que c'est la solution miracle pour cacher des mots de passe ou des données confidentielles. En fait, on peut scanner le système avec des outils spécifiques ou Get-ChildItem à la recherche de fichiers qui ont un stream supplémentaire que le $DATA par défaut.

C'est un peu hors sujet, mais pour effectuer cette analyse à partir d'un dossier courant comme point de départ :

Get-ChildItem -Recurse | ForEach { Get-Item $_.FullName -Stream * } | Where stream -ne ':$Data'

Cette commande fera ressortir notre fichier Pays.txt et son stream "Creds" ?. Il est fort possible des documents Office soient également mis en avant par la sortie de la commande avec un stream nommé "Zone.Identifier". Il contient un ID qui permet au système de connaître la zone d'appartenance de ce fichier (intranet, internet, etc.. vis-à-vis des zones IE).

Nous venons de voir, dans le détail, comment utiliser la commande Get-Content de PowerShell.

author avatar
Florian BURNEL Co-founder of IT-Connect
Ingénieur système et réseau, cofondateur d'IT-Connect et Microsoft MVP "Cloud and Datacenter Management". Je souhaite partager mon expérience et mes découvertes au travers de mes articles. Généraliste avec une attirance particulière pour les solutions Microsoft et le scripting. Bonne lecture.
Partagez cet article Partager sur Twitter Partager sur Facebook Partager sur Linkedin Envoyer par mail

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.