Vous êtes sur la page 1sur 11

Get-Content : comment lire le contenu d’un

fichier en PowerShell ?
Sommaire [-]
 I. Présentation
 II. Lire simplement le contenu d'un fichier
 III. Le tail de Linux à la mode PowerShell
 IV. Récupérer les X premières lignes d'un fichier
 V. NTFS : consulter un stream secret dans un fichier

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"

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).

Partie2
Gérez vos fichiers et dossiers simplement avec PowerShell
Apprenez à vous repérer dans le système de fichiers avec PowerShell
Démarrez votre serveur et lancez PowerShell, vous devriez vous trouver dans le répertoire
par défaut utilisateur : C:\Users\Administrateurs. Bien sûr que si vous vous connectez avec
un autre utilisateur, vous serez par défaut dans le répertoire utilisateur. Par savoir où l’on se
situe, on va utiliser la commande Get-Location :
PS C:\Users\Administrateur> Get-Location
Path
----
C:\Users\Administrateur
Cool, nous voyons que nous sommes dans notre bon répertoire. C’est la même commande
que pwd sous Linux (ou Unix).

Pour afficher le contenu d’un dossier, utilisez la commande Get-ChildItem :


PS C:\Users\Administrateur> Get-ChildItem
Répertoire : C:\Users\Administrateur
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 28/06/2019 11:59 3D Objects
d-r--- 28/06/2019 11:59 Contacts
d-r--- 07/07/2019 17:59 Desktop
d-r--- 28/06/2019 11:59 Documents
d-r--- 28/06/2019 11:59 Downloads
d-r--- 28/06/2019 11:59 Favorites
d-r--- 28/06/2019 11:59 Links
d-r--- 28/06/2019 11:59 Music
d-r--- 28/06/2019 11:59 Pictures
d-r--- 28/06/2019 11:59 Saved Games
d-r--- 28/06/2019 11:59 Searches
d-r--- 28/06/2019 11:59 Videos
Pour ceux qui ont connu le DOS, cela est équivalent à la commande dir.
PS C:\Users\Administrateur> dir
Répertoire : C:\Users\Administrateur
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 28/06/2019 11:59 3D Objects
d-r--- 28/06/2019 11:59 Contacts
d-r--- 07/07/2019 17:59 Desktop
d-r--- 28/06/2019 11:59 Documents
d-r--- 28/06/2019 11:59 Downloads
d-r--- 28/06/2019 11:59 Favorites
d-r--- 28/06/2019 11:59 Links
d-r--- 28/06/2019 11:59 Music
d-r--- 28/06/2019 11:59 Pictures
d-r--- 28/06/2019 11:59 Saved Games
d-r--- 28/06/2019 11:59 Searches
d-r--- 28/06/2019 11:59 Videos
Bon promis, je ne vous parle plus des commandes MS-DOS, il faut vivre avec son temps,
utilisons maintenant uniquement le PowerShell !

Allez, nous allons créer un répertoire de sauvegarde SAVE dans notre dossier utilisateur ;
utilisons la commande New-Item :
PS C:\Users\Administrateur> New-Item -Name "SAVE" -ItemType Directory
Répertoire : C:\Users\Administrateur
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 17/09/2019 10:38 SAVE
Bon, si on visualise le contenu de notre répertoire courant, nous verrons bien que le
dossier SAVE a bien été créé.

On peut également utiliser la commande New-Item pour créer un fichier


texte utilisateurs.txt en tapant :
PS C:\Users\Administrateur> New-Item -Name "utilisateurs.txt" -ItemType
File
Je peux utiliser aussi cette commande pour créer un fichier texte groupes.txt et y insérer du
texte en tapant :
PS C:\Users\Administrateur> New-Item -Name "groupes.txt" -ItemType File -
Value "Voici la Liste des Groupes"
Pour visualiser le contenu du fichier texte, tapez la commande suivante :

PS C:\Users\Administrateur> notepad.exe groupes.txt

Éditez votre fichier une fois ouvert avec PowerShell


Manipulez vos fichiers avec PowerShell
Nous allons copier notre fichier utilisateurs.txt dans notre répertoire SAVE en tapant la
commande suivante :

PS C:\Users\Administrateur> Copy-Item -Path utilisateurs.txt -Destination


SAVE
Si nous allons voir le contenu de SAVE, nous verrons que notre
fichier utilisateurs.txt a bien été copié.
PS C:\Users\Administrateur> Get-ChildItem SAVE
Répertoire : C:\Users\Administrateur\SAVE
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06/07/2019 15:35 0 utilisateurs.txt
Vous remarquerez que pour visualiser le contenu de SAVE, j’ai utilisé la
commande Get-ChildItem avec un attribut (SAVE) sans m’être déplacé dans mon
répertoire SAVE ; pensez à utiliser les attributs avec vos commandes PowerShell,
elles vous permettent d’aller souvent plus vite.

Bon c’est cool, et si je veux déplacer maintenant le fichier groupes.txt, j’utiliserai la


commande suivante :
PS C:\Users\Administrateur> Move-Item -Path C:\Users\Administrateur\
groupes.txt -Destination C:\Users\Administrateur\SAVE
Vérifions le contenu de nos 2 répertoires, notre fichier groupes.txt a bien été
déplacé.
PS C:\Users\Administrateur> Get-ChildItem
Répertoire : C:\Users\Administrateur
Mode LastWriteTime Length Name
---- ------------- ------ ----
d-r--- 28/06/2019 11:59 3D Objects
d-r--- 28/06/2019 11:59 Contacts
d-r--- 07/07/2019 17:59 Desktop
d-r--- 28/06/2019 11:59 Documents
d-r--- 28/06/2019 11:59 Downloads
d-r--- 28/06/2019 11:59 Favorites
d-r--- 28/06/2019 11:59 Links
d-r--- 28/06/2019 11:59 Music
d-r--- 28/06/2019 11:59 Pictures
d-r--- 28/06/2019 11:59 Saved Games
d-r--- 28/06/2019 11:59 Searches
d-r--- 28/06/2019 11:59 Videos
-a---- 06/07/2019 15:35 0 utilisateurs.txt
PS C:\Users\Administrateur> Get-ChildItem SAVE
Répertoire : C:\Users\Administrateur\SAVE
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06/07/2019 15:37 26 groupes.txt
-a---- 06/07/2019 15:35 0 utilisateurs.txt
Bon, si vous regardez de plus près, je viens de faire le déplacement du
fichier groupes.txt différemment de la copie du fichier utilisateurs.txt. Eh oui, on a utilisé ce
que l’on appelle les chemins relatifs pour la copie du fichier utilisateurs.txt, c’est-à-dire
que l’on n'a pas utilisé d’anti-slash. Si j’utilise les chemins absolus (anti-slash en préfixe du
chemin), je dois taper le lien complet du fichier et du dossier de destination, et c’est ce que je
viens de faire pour le déplacement du fichier groupes.txt.

Vous devez maîtriser les deux types de déplacement car cela va plus vite d’utiliser
les chemins relatifs mais on peut faire des erreurs ; on privilégiera plus souvent
les chemins absolus. Et surtout, n’hésitez pas à utiliser l’autocomplétion, vous
allez beaucoup plus vite et vous évitez les erreurs de frappe.

On peut renommer également notre fichier utilisateurs.txt dans notre


répertoire SAVE par utilisateurs_save.txt en tapant la commande suivante :
PS C:\Users\Administrateur> Rename-Item -Path C:\Users\Administrateur\SAVE\
utilisateurs.txt -NewName C:\Users\Administrateur\SAVE\
utilisateurs_save.txt
On peut voir que notre fichier utilisateurs.txt a bien été renommé
en utilisateurs_save.txt :
PS C:\Users\Administrateur> Get-ChildItem SAVE
Répertoire : C:\Users\Administrateur\SAVE
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 06/07/2019 15:37 26 groupes.txt
-a---- 06/07/2019 15:35 0 utilisateurs_save.txt
Tiens, je souhaite créer un sous-dossier OU dans SAVE, comment faire ? Je peux
utiliser la commande New-Item comme ceci :
PS C:\Users\Administrateur> New-Item -Path C:\Users\Administrateur\SAVE\OU
-ItemType Directory
Répertoire : C:\Users\Administrateur\SAVE
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 17/09/2019 10:45 OU
PS C:\Users\Administrateur> Get-ChildItem C:\Users\Administrateur\SAVE
Répertoire : C:\Users\Administrateur\SAVE
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 17/09/2019 10:45 OU
-a---- 06/07/2019 15:37 26 groupes.txt
-a---- 06/07/2019 15:35 0 utilisateurs_save.txt
Maintenant, nous allons copier le contenu de notre dossier personnel SAVE dans un
autre dossier SAUVEGARDE, mais qui sera à la racine du disque dur.

Allons-y, créons d’abord un dossier SAUVEGARDE à la racine du disque dur en


tapant :
PS C:\Users\Administrateur> New-Item -Path "C:\SAUVEGARDE" -ItemType
Directory
Répertoire : C:\

Mode LastWriteTime Length Name


---- ------------- ------ ----
d----- 17/09/2019 10:46 SAUVEGARDE
Et voilà :
PS C:\Users\Administrateur> Get-ChildItem C:\
Répertoire : C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 15/09/2018 09:19 PerfLogs
d-r--- 06/07/2019 19:27 Program Files
d----- 15/09/2018 18:38 Program Files (x86)
d----- 17/09/2019 10:46 SAUVEGARDE
d-r--- 17/09/2019 10:35 Users
d----- 17/09/2019 10:30 Windows
Bon, ben nous allons maintenant copier le contenu de notre répertoire SAVE du
dossier utilisateur Administrateur vers ce dossier SAUVEGARDE en tapant :
PS C:\Users\Administrateur> Copy-Item -Path C:\Users\Administrateur\SAVE\ -
Destination C:\SAUVEGARDE\ -Recurse
PS C:\Users\Administrateur> Get-ChildItem C:\SAUVEGARDE

Répertoire : C:\SAUVEGARDE
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 17/09/2019 10:47 SAVE
Nous voyons bien que le dossier SAVE a bien été copié dans le
dossier SAUVEGARDE. Et si nous vérifions le contenu du dossier SAVE dans le
dossier SAUVEGARDE, comme ceci...
PS C:\Users\Administrateur> Get-ChildItem C:\SAUVEGARDE\SAVE
Répertoire : C:\SAUVEGARDE\SAVE
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 17/09/2019 10:47 OU
-a---- 06/07/2019 15:37 26 groupes.txt
-a---- 06/07/2019 15:35 0 utilisateurs_save.txt
... l’attribut -Recurse nous a permis de copier les fichiers et les sous-dossiers, très pratique
pour faire des sauvegardes de dossiers et de sous-dossiers.

Par contre, cette commande a copié le contenu du dossier SAVE du répertoire


personnel Administrateur dans SAUVEGARDE ; mais j’aurai voulu qu’il ne recrée
pas un dossier SAVE dans C:\SAUVEGARDE.

Nous allons donc supprimer le dossier SAUVEGARDE en tapant la commande


suivante, puis en tapant T pour tout supprimer :
PS C:\Users\Administrateur> Remove-Item C:\SAUVEGARDE\
Confirmer
L'élément situé à l'emplacement C:\SAUVEGARDE\ a des enfants et le
paramètre
Recurse n'a pas été spécifié.
Si vous continuez, tous les enfants seront supprimés avec l'élément. Êtes-
vous
sûr de vouloir continuer ?
[O] Oui [T] Oui pour tout [N] Non [U] Non pour tout [S] Suspendre [?] Aide
(la valeur par défaut est « O ») :T
Vérifions que le dossier SAUVEGARDE a bien été supprimé :
PS C:\Users\Administrateur> Get-ChildItem C:\
Répertoire : C:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 15/09/2018 09:19 PerfLogs
d-r--- 06/07/2019 19:27 Program Files
d----- 15/09/2018 18:38 Program Files (x86)
d-r--- 17/09/2019 10:35 Users
d----- 17/09/2019 10:30 Windows
Bon, ben nous allons maintenant copier notre répertoire SAVE du dossier
utilisateur Administrateur vers le dossier SAUVEGARDE en tapant ceci, mais en ne
créant pas le répertoire SAVE :
PS C:\Users\Administrateur> Copy-Item -Path C:\Users\Administrateur\SAVE\ -
Destination C:\SAUVEGARDE\ -Recurse
Et maintenant, vérifions le contenu du répertoire SAUVEGARDE :
PS C:\Users\Administrateur> Get-ChildItem C:\SAUVEGARDE
Répertoire : C:\SAUVEGARDE
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 17/09/2019 10:57 OU
-a---- 06/07/2019 15:37 26 groupes.txt
-a---- 06/07/2019 15:35 0 utilisateurs_save.txt
Super, on a bien copié le contenu de notre répertoire utilisateur Administrateur vers
le dossier SAUVEGARDE.

Vous aimerez peut-être aussi