FreshRSS

🔒
❌ À propos de FreshRSS
Il y a de nouveaux articles disponibles, cliquez pour rafraîchir la page.
À partir d’avant-hierFlux principal

Comment personnaliser le Prompt de son environnement PowerShell ?

17 juin 2021 à 11:00

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.

PowerShell $host

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

Créer profil PowerShell personnalisé

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 :

PowerShell : nom de la fenêtre égal au répertoire courant
PowerShell : nom de la fenêtre égal au répertoire courant

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 :

  1. Si j’ai ouvert PowerShell en tant qu’administrateur, la mention Elevated apparaît dans le prompt.
  2. Le nom de l’utilisateur courant. Toujours pratique, notamment quand on jongle entre les utilisateurs.
  3. Le hostname de la machine.
  4. Le répertoire courant. Je n’affiche pas le chemin UNC dans son intégralité, mais juste le nom du répertoire courant.
  5. La branche Git sur laquelle je me trouve, si le répertoire est tracké par Git.
  6. L’ID de la commande par rapport à l’historique
  7. Le temps d’exécution de la dernière commande
  8. 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 !

The post Comment personnaliser le Prompt de son environnement PowerShell ? first appeared on IT-Connect.

Comment imposer des prérequis dans ses scripts PowerShell ?

16 juin 2021 à 13:00

I. Présentation

Vous commencez à avoir une belle collection de scripts PowerShell, mais vous ne savez jamais comment les lancer ? Pour celui-ci, faut-il avoir les droits administrateur ? Faut-il le lancer en tant qu’utilisateur classique ? Doit-on le lancer dans Windows PowerShell version 5.1, ou plutôt dans PowerShell 7 ? Et côté modules, que faut-il installer sur la machine avant de lancer ce script ?

Si vous vous posez ces questions à chaque fois que vous souhaitez lancer un script, alors cet article est pour vous.

Car vous ne le savez peut-être pas, mais il est tout à fait possible d’imposer des prérequis à respecter dans un script PowerShell, sous peine de quoi le script refusera de se lancer, car les prérequis ne sont pas respectés.

Plus besoin d’ouvrir le script dans un éditeur et de le parcourir pour vérifier quels sont les prérequis en fonction des commandes inscrites.

II. Prérequis

  • Windows PowerShell version 5.1 ou PowerShell 7

III. L’instruction Requires en PowerShell

A. Quelques exemples

Certains d’entre vous ont contourné le problème en ajoutant dans un commentaire en début de script que celui-ci doit être lancé en tant qu’administrateur. D’autres font un test en début de script pour vérifier si la session PowerShell est une session de type administrateur ou non.

Mais ces solutions ne sont pas viables : l'une oblige à modifier le script et consulter les commentaires systématiquement avant de le lancer, l'autre est plutôt lourde à coder et en fonction de votre environnement (notamment pour PowerShell Core sur des machines autres que Windows), votre code pourrait ne pas fonctionner.

Il y a pourtant bien plus simple : l’instruction Requires.

Il s’agit d’une instruction très simple, qui demande à PowerShell de vérifier avant toute exécution du script les prérequis listés :

  • La version minimum de PowerShell à utiliser
  • Les modules qui doivent être préalablement installés, ainsi que leur version
  • L’édition de PowerShell (Desktop ou Core) à utiliser
  • Une session PowerShell ouverte en tant qu’administrateur

L’un de ces prérequis n’est pas respecté ? Le script refuse de se lancer. Par exemple, j’ai ici ajouté une instruction demandant à être administrateur, mais j’ai lancé mon script en tant qu’utilisateur.

PowerShell #Requires

Autre exemple : cette fois, j’ai indiqué que le prérequis était de lancer le script sur une édition Desktop. Autrement dit, il ne peut se lancer que sur Windows PowerShell.

Pour le vérifier, j’ai tenté de lancer le script sur PowerShell édition Core (version 7), et sur Windows PowerShell (édition Desktop, version 5.1). Et voici le résultat :

B. Comment ça marche ?

Concrètement, comment ça marche ? Vous allez voir, c’est d’une simplicité enfantine.

Il vous suffit d’ajouter l’instruction #Requires dans votre script, suivi du paramètre choisi.

Si vous avez plusieurs prérequis différents à respecter, par exemple lancer un script en tant qu’administrateur tout en utilisant PowerShell version 5.1 minimum, il vous faudra mettre chaque instruction sur une ligne séparée. Et ... C’est tout !

Vous pouvez glisser cette instruction n’importe où dans votre script, mais je vous conseille pour des raisons de maintenabilité de l’ajouter au début. Avant toute exécution de votre script, PowerShell va chercher si une instruction #Requires est présente, et si c’est le cas, va vérifier que les prérequis sont bien respectés.

Note : Veillez bien à respecter le # avant le Requires. Bien que le dièse est habituellement utilisé pour ajouter des commentaires, cette instruction ne fonctionnera pas sans. Voyez ça comme un commentaire spécial.

IV. Les paramètres de #Requires en PowerShell

Vous pouvez utiliser les paramètres suivants avec l’instruction Requires :

A. -Version

Ce paramètre sert à spécifier la version minimum de PowerShell à respecter afin de pouvoir lancer le script. Vous pouvez indiquer une version majeure (par exemple 5), ou une version mineure, par exemple 5.1.

#Requires -Version 5.1

PowerShell devra être à minima en version 5.1 pour lancer ce script.

#Requires -Version 7

PowerShell devra être à minima en version 7 afin d'exécuter ce script.

B. -PSEdition

Ce paramètre sert à spécifier l'édition de PowerShell à respecter. Pour rappel, si vous utilisez PowerShell en version 5.1, ou via Windows PowerShell (la version préinstallée sur votre OS), vous êtes en édition Desktop. Si vous utilisez PowerShell en version 7, ou sur un Linux / MacOS, vous êtes en version Core.

#Requires -PSEdition Desktop

Impose l'utilisation de Windows PowerShell pour lancer le script.

#Requires -PSEdition Core

Impose l'utilisation de PowerShell en version Core. A privilégier pour les scripts cross-platform.

Note : Vous pouvez coupler ce paramètre avec le paramètre -Version afin d'avoir un contrôle plus fin sur vos prérequis.

C. -RunAsAdministrator

Sans nul doute le paramètre qui vous servira le plus souvent, et qui vous permet d'imposer qu'une session soit lancée en tant qu'administrateur pour que le script s'exécute.

#Requires -RunAsAdministrator

D. -PSSnapin

Ce paramètre sert à préciser les snap-ins requis pour l'exécution du script. Vous pouvez également indiquer, sur la même ligne (et de manière optionnelle) la version du snap-in à utiliser.

#Requires -PSSnapin DiskSnapin -Version 1.2

Note : Pour tout savoir sur les snapins, rendez-vous ici.

E. -Modules

Ce paramètre sert à spécifier les modules devant être installés sur votre machine préalablement avant l'exécution du script. Le module est absent ? Le script refuse de s'exécuter.

Optionnellement, vous pouvez préciser la version minimum, la version exacte ou la version maximum à utiliser pour ce module. Petite précision d'importance : vous ne pouvez utiliser qu'un seul de ces paramètres à la fois, à vous donc de choisir celui qui se rapproche le plus de ce que vous souhaitez faire.

Voici quelques exemples :

#Requires -Modules ActiveDirectory

➡ Le module ActiveDirectory doit être installé.

#Requires -Modules ActiveDirectory, AzureAD

➡ Les modules ActiveDirectory & AzureAD doivent être préalablement installés.

#Requires -Modules @{ModuleName= "AzureRM.Netcore" ; ModuleVersion= "0.12.0"}

➡ Le module AzureRM.Netcore doit être présent minimum en version 0.12.0.

#Requires -Modules @{ModuleName= "AzureRM.Netcore" ; RequiredVersion= "0.12.0"}

➡ Le module AzureRM.Netcore doit être présent exactement en version 0.12.0.

#Requires -Modules @{ModuleName= "AzureRM.Netcore" ; MaximumVersion= "0.12.0"}

➡ Le module AzureRM.Netcore doit être présent et au maximum en version 0.12.0.

Note : Si l'on souhaite préciser la version du module à utiliser, on passe cette information en plus du nom dans une hashtable : la notation @{}

Vous l’aurez compris, plus besoin de vous lancer dans des tests compliqués en début de script pour vérifier les modules installés ou non, si la session est une session administrateur, etc.

Avec l’instruction Requires, vous allez littéralement vous simplifier la vie !

The post Comment imposer des prérequis dans ses scripts PowerShell ? first appeared on IT-Connect.
❌