Comment personnaliser le Prompt de son environnement PowerShell ?
Sommaire
I. Présentation
Les linuxiens vous le diront, customiser son environnement, le nom de son terminal, son prompt, c'est utile / indispensable (rayer la mention inutile).
Non seulement on s'approprie les outils mis à notre disposition, mais en plus cela nous permet d'afficher des informations utiles et de les garder à l'oeil, de gagner du temps, et le tout en apprenant comment notre terminal fonctionne.
Et vous êtes nombreux à l'ignorer, mais PowerShell vous offre également cette possibilité.
Dans cet article, je vais vous montrer comment personnaliser votre environnement PowerShell, notamment :
- Comment renommer la fenêtre de son terminal manuellement
- Comment le faire automatiquement
- Comment modifier le prompt par défaut (un peu tristounet et austère)
- Et enfin, je vais vous montrer quelles sont les modifications que j'utilise au quotidien dans mon environnement PowerShell.
Allez, c'est parti !
II. Prérequis
- PowerShell version 5.1 ou +.
A noter que pour ce tutoriel, j’ai utilisé PowerShell version 7 sur une distribution Ubuntu. Juste pour vous montrer que oui, c'est possible, et que oui PowerShell 7 (ou PowerShell Core) ça fonctionne plutôt (très) bien sous Linux.
III. Modifier le titre de sa fenêtre terminal PowerShell
En PowerShell, pour interagir avec notre terminal, et donc le customiser, il faut passer par la variable $host.
Note : La commande Get-Host fonctionne également, et vous retourne la valeur de $host.
On peut voir que $host contient un certain nombre de propriétés, dont UI à laquelle nous allons nous intéresser maintenant.
La propriété UI est en fait un objet de type System.Management.Automation.Internal.Host.InternalHostUserInterface.
On va donc aller voir ce que contient cet objet :
$host.UI
On peut alors voir que $host.UI contient un nouvel objet, dénommé RawUI. On continue donc notre investigation en effectuant :
$host.UI.RawUI
On obtient alors une liste de propriétés liées à notre terminal, dont une plus particulièrement nous intéresse : WindowTitle.
Elle contient actuellement une chaîne de caractères : "PowerShell", qui est actuellement le nom donné à notre fenêtre. Logiquement, si on change cette chaîne de caractères, on change donc le nom du terminal.
Testons ça de suite.
Pour renommer la fenêtre PowerShell, il nous suffit donc de donner une nouvelle valeur à cette propriété WindowTitle, comme ceci :
$host.UI.RawUI.WindowTitle = "Test"
Et voilà le résultat : notre fenêtre est renommée et s'appelle maintenant "Test".
Note : de la même manière, vous pouvez modifier la couleur de la police d’écriture, du fond, la taille de votre fenêtre, et ainsi de suite. N’ayez pas peur d’expérimenter à ce stade. Si vous vous trompez, les changements ne sont pas persistants, il vous suffit donc d'ouvrir un nouveau terminal et de recommencer.
Allons un peu plus loin. Vous vous en doutiez sûrement, mais il est tout à fait possible de passer des variables dans le titre.
Par exemple j’ai créé une variable $t, qui contient la chaîne de caractères suivante : <3
Si je reprends la commande précédente, je vais donc passer la variable dans le nom du titre de cette manière :
$host.UI.RawUI.WindowTitle = "I $t IT-Connect"
Ma fenêtre est donc renommée en "I <3 IT-Connect".
Plutôt pratique pour afficher l’état d’avancement d’une migration dans un terminal ou pour se repérer dans de multiples fenêtres.
Ok, autre exemple.
Que se passe t-il si je tape la commande suivante dans mon terminal ?
$host.UI.RawUI.WindowTitle = "PS >> User: Thibault >> Current DIR: $((Get-Location).Path)"
Et bien la commande (Get-Location).Path va s’exécuter, et le résultat va s’afficher directement dans la fenêtre de mon terminal. Autrement dit ma fenêtre PowerShell va être renommée avec le nom du répertoire dans lequel je me trouve actuellement.
Seul problème, si je change de répertoire cela ne se met pas à jour automatiquement. Et c’est normal, puisque jusqu’à maintenant j’ai exécuté des commandes one shot.
Donc dans la logique actuelle, si je veux mettre à jour le nom de ma fenêtre à chaque fois que je change de répertoire, je dois donc relancer la même commande, encore et encore, après chaque opération.
Vous en conviendrez, ce n'est absolument pas pratique et viable sur le long terme?
Alors comment automatiser ça ? Via une fonction que l’on va enregistrer dans le profil utilisateur.
IV. Création d'un profil utilisateur personnalisé pour PowerShell
Première chose : avant de modifier ce profil, il nous faut déjà savoir où celui-ci est stocké. Pour cela rien de plus simple, il vous suffit d’accéder au contenu de la variable $profile. A une nuance près : il existe plusieurs profils utilisateurs sous PowerShell. Nous allons nous intéresser dans notre cas au profile CurrentUserAllHosts :
$profile.CurrentUserAllHosts
Note : pour tout comprendre sur les différents profils PowerShell, je vous redirige sur cet excellent article de Microsoft, en anglais : https://devblogs.microsoft.com/scripting/understanding-the-six-powershell-profiles/
Dans mon cas, mon fichier de profil PowerShell est stocké à l’endroit suivant :
/home/thibault/.config/powershell/profile.ps1
Pour rappel, j’utilise PowerShell 7 sur une distribution Ubuntu pour ce tutoriel, votre profil sera donc stocké à un autre endroit sur Windows.
Mais surprise, si j’essaye de modifier ce fichier, il n’existe pas. Pourquoi ? Car nous n’utilisons pas de profil PowerShell personnalisé pour le moment.
On va donc commencer par créer ce fichier (chemin à adapter, en particulier sous Windows) et le dossier "powershell" qui le conient :
New-Item -Path /home/thibault/.config/ -ItemType Directory -Name powershell New-Item -Path /home/thibault/.config/powershell -ItemType File -Name profile.ps1
Bien ! Maintenant que notre fichier profil est créé, on va l’ouvrir avec notre éditeur préféré. Dans mon cas, j’utilise VsCode, donc logiquement je vais taper la commande suivante :
code /home/thibault/.config/powershell/profile.ps1
On va maintenant pouvoir commencer la personnalisation de notre environnement. Commençons par ajouter la fonction suivante :
$CurrentUser= (Get-ChildItem Env:\USERNAME).Value function Prompt { $host.UI.RawUI.WindowTitle = "PS >> User: $CurrentUser >> Current DIR: $((Get-Location).Path)" Return " " }
Il nous reste maintenant qu'à fermer notre terminal, puis à le rouvrir pour tester ce que l'on vient de coder. Le profil personnalisé est alors chargé, et notre fonction s’exécutera à chaque fois que l’on effectuera une nouvelle commande PowerShell.
Je me déplace dans le répertoire /Repos, le nom de la fenêtre change :
Je change à nouveau de répertoire pour aller dans /home, le nom de la fenêtre change à nouveau :
Bon, par contre vous avez remarqué un énoooorme souci sur les captures d’écran : c’est que le prompt a tout bonnement disparu !
Pourquoi ? Car dans notre fonction Prompt, on n’a strictement rien indiqué sur quoi afficher dans le prompt : celui-ci est donc vide. On va s’atteler à changer ça.
V. Modification du prompt PowerShell
Par défaut, PowerShell affiche PS <répertoire-courant> > en tant que prompt. Dans mon cas, cela donne :
PS /home/thibault >
On va donc rouvrir notre fichier de profil PowerShell, et modifier notre fonction Prompt pour recréer ce prompt par défaut :
code /home/thibault/.config/powershell/profile.ps1
Puis, on va ajouter au début de notre fonction Prompt les 3 lignes suivantes :
Write-Host -NoNewLine "PS " Write-Host -NoNewLine $((Get-Location).Path) Write-Host -NoNewLine ">"
Et oui, ça ne fonctionne absolument pas comme Linux où on stocke dans une variable $PS1 le contenu du prompt. Ici, on l’écrit à l’écran, tout simplement.
A noter qu’on utilise ici le paramètre -NoNewLine, qui nous permet de tout écrire sur la même ligne, et donc de générer le prompt. Autrement, chaque itération de Write-Host ferait par défaut un saut à la ligne, ce qui n’est pas vraiment ce qu'on attend d'un prompt.
On sauvegarde alors notre fichier profil, et comme tout à l’heure on lance un nouveau terminal PowerShell pour observer le résultat.
C’est tout de suite mieux !
Allez, un dernier pour la route, on va encore modifier notre prompt, cette fois pour y ajouter :
- L’heure
- Le nombre de répertoires / fichiers dans le présent dossier
- Un peu de couleurs pour égayer tout ça
Ce qui nous donne :
function Prompt { Write-Host -NoNewLine "[" -ForegroundColor Yellow Write-Host -NoNewLine (Get-Date -Format HH:mm:ss) -ForegroundColor White Write-Host -NoNewLine "]" -ForegroundColor Yellow Write-Host -NoNewLine $((Get-Location).Path) -ForegroundColor White Write-Host -NoNewLine " | " -ForegroundColor Yellow Write-Host -NoNewLine (Get-ChildItem -Path (Get-Location)).Count -ForegroundColor White Write-Host -NoNewLine " >" -ForegroundColor Red $host.UI.RawUI.WindowTitle = "PS >> User: $CurrentUser >> Current DIR: $((Get-Location).Path)" Return " " }
Allez, je vous explique tout ça :
- (Get-Date -Format HH:mm:ss) nous donne l’heure au format 24 heures (les 2 H majuscules). Si vous formatez la date au format hh:mm:ss, vous obtiendrez l’affichage de l’heure au format 12 heures, version US.
- $((Get-Location).Path) donne le répertoire actuel de travail, comme on l’a vu précédemment.
- Enfin, (Get-ChildItem -Path (Get-Location)).Count compte le nombre de sous-dossiers et de fichiers présents dans le répertoire de travail actuel.
- Le paramètre -ForegroundColor quant à lui permet de modifier la couleur de la police d’écriture.
Note : Si vous souhaitez modifier la couleur de fond, vous utiliserez -BackgroundColor
Voyons ce que ça donne une fois le terminal PowerShell relancé :
Plutôt sympa, non ? Il n’y a plus qu’à laisser parler votre créativité.
VI. Mes préférences persos
De mon côté, j’aime avoir à portée de main des infos utiles, histoire de gagner du temps.
Voici les infos que je juge utile au quotidien, et qui apparaissent dans mon shell PowerShell :
- Si j’ai ouvert PowerShell en tant qu’administrateur, la mention Elevated apparaît dans le prompt.
- Le nom de l’utilisateur courant. Toujours pratique, notamment quand on jongle entre les utilisateurs.
- Le hostname de la machine.
- Le répertoire courant. Je n’affiche pas le chemin UNC dans son intégralité, mais juste le nom du répertoire courant.
- La branche Git sur laquelle je me trouve, si le répertoire est tracké par Git.
- L’ID de la commande par rapport à l’historique
- Le temps d’exécution de la dernière commande
- Enfin, dans le nom de ma fenêtre, j’affiche le chemin d’accès complet au répertoire courant. Dans quelques cas particuliers, notamment lorsque j’ai plusieurs scripts de migration qui tournent en parallèle, je renomme la fenêtre avec le nom du script, ou son contexte d’exécution. Par exemple : « Migration Floirac ».
Si vous êtes curieux, voici ce que ça donne sous Linux.
Et en utilisant le même profil sur PowerShell 7 sur mon PC Windows, on obtient ceci :
Et ceci côté Windows PowerShell version 5.1 :
Le comportement est légèrement différent sous Windows, car oui dans mon profil je teste si PowerShell tourne sous Linux, MacOS, ou Windows, et mon prompt évolue en fonction de cela.
Pour voir en détail à quoi ressemble ma fonction Prompt dans mon profil PowerShell, rendez-vous sur mon espace Github.
Maintenant c'est à vous de jouer et de laisser parler votre créativité. Un seul mot d'ordre : dites adieu au prompt austère par défaut de PowerShell !