Guide de portée des variables dans PowerShell : Utilisation de la portée dans les scripts et les modules

PowerShell

PowerShell utilise des variables pour stocker des informations qui serviront par la suite. Les variables permettent également de modifier facilement les valeurs à plusieurs endroits en changeant la définition de la variable. Vous pouvez stocker des informations telles que le nom, le chemin et le résultat des commandes dans une variable.

À mesure que vous acquerrez une bonne connaissance de PowerShell, la portée des variables commencera probablement à jouer un rôle dans l’écriture des scripts, des fonctions et des modules. Dans cet article, je vais aborder les notions de base concernant la portée des variables dans PowerShell et fournir des exemples d’utilisation des portées dans les scripts et modules PowerShell.

Obtenir le cours vidéo gratuit sur les notions essentielles de PowerShell et d’Active Directory

Je le recommande aux nouveaux utilisateurs et aux utilisateurs avancés de PowerShell. Créer un outil Active Directory est une excellente expérience d’apprentissage.

En plus d’apprendre à maîtriser la portée, vous avez accès à une série d’outils PowerShell à titre de ressources complémentaires, comme des éditeurs, des modules et des formations qui vous permettront d’améliorer votre niveau de compétence PowerShell.

Que sont les portées dans PowerShell ?

La portée dans PowerShell protège les variables et autres artefacts en limitant l’emplacement où ils peuvent être lus et modifiés. Les niveaux de portée protègent les éléments qui ne doivent pas être modifiés. PowerShell prend en charge les portées suivantes :

  • Global : Cette portée est disponible lorsque vous ouvrez une console PowerShell ou créez une nouvelle instance d’exécution ou une nouvelle session. Les variables automatiques et préférentielles de PowerShell sont présentes et disponibles dans la portée globale. L’ensemble des variables, alias et fonctions définis dans votre profil PowerShell sont également disponibles dans la portée globale.
  • Script : Il s’agit de la portée créée lorsque vous exécutez un script. Les variables définies dans le script sont uniquement disponibles pour la portée du script et non pour la portée globale ou parente.
  • Local : Il s’agit de la portée actuelle de l’exécution d’une commande ou d’un script. Par exemple, les variables définies dans la portée script sont considérées comme sa portée locale.
  • Private : Bien qu’il ne s’agisse pas techniquement d’une portée, l’utilisation de cette option permet d’empêcher la visibilité d’une variable en dehors de la portée où la variable est définie.

Les portées fonctionnent selon une hiérarchie, ce qui signifie que la portée globale est la portée parente. Les variables définies dans la portée globale peuvent automatiquement être visualisées dans la portée enfant. Toutefois, les variables définies dans la portée enfant ne sont pas disponibles dans la portée parente.

Les portées PowerShell suivent quelques règles de base :

  • Les portées s’emboîtent les unes dans les autres. La portée extérieure est la portée parente, et toute portée imbriquée est une portée enfant de la portée parente.
  • Un élément est disponible dans la portée où il est défini et dans toutes les portées enfant, sauf s’il se voit explicitement appliquer l’option privée.
  • Un élément créé dans une portée ne peut être modifié que dans la portée où il a été défini. Un autre élément portant le même nom mais situé dans une portée différente peut masquer l’élément original, mais il ne remplace pas ni ne modifie ce dernier.

Portée globale ou portée script ?

Voyons quelques exemples concrets des différentes portées. Prenons un script qui définit une variable et l’affiche à l’écran :

  1. $greeting = “Hello, World!”
  2. $greeting

Ce script définit la variable $greeting dans la portée script (ou locale). Toutefois, cette variable et sa valeur ne seront pas disponibles pour la console PowerShell, c’est-à-dire la portée parente. Examinez la sortie des commandes PowerShell ici :

Portée globale ou portée script ?

J’affiche la valeur actuelle de la variable $greeting dans la console (ou la portée globale) ; comme prévu, celle-ci est vide. J’exécute le fichier script dans lequel $greeting est défini et affiché à l’écran. Une fois le script terminé, j’affiche à nouveau la valeur de $greeting dans la console PowerShell, et celle-ci est toujours vide. C’est normal, car la variable $greeting se trouve dans la portée script enfant et non dans la portée globale parente.

Examinons l’inverse. Au lieu de définir la valeur de $greeting dans le script, définissons-la dans la portée globale. Le script affiche alors la valeur de la variable $greeting à l’intérieur du script car il en a hérité de la portée globale.

Variable héritée de la portée globale

Dans le script, je n’ai pas défini ni modifié la variable $greeting. J’ai seulement affiché sa valeur. La chaîne de bienvenue « greeting » a été héritée de la console en tant que portée parente par le fichier script en tant que portée enfant.

Utilisation des modificateurs de portée

Dans les exemples précédents, nous avons vu comment une variable définie dans la portée du script enfant ne pouvait pas être consultée par la portée globale. Toutefois, il est possible d’utiliser des modificateurs de portée pour changer la portée de la variable définie. Voici quelques modificateurs de portée :

 

Modificateur de portée Utilisation
global : La variable existe dans la portée globale
local : La variable existe dans la portée locale
private : La variable est seulement visible dans la portée actuelle
script : La variable existe dans la portée script, qui est la portée la plus proche du fichier script, ou dans la portée globale s’il n’y en a pas

 

Par exemple, je peux utiliser le préfixe $global: sur une variable à l’intérieur d’un script pour modifier une valeur de variable que j’ai déjà définie dans la portée parente globale. Examinez le script et la sortie de console ci-dessous :

Utilisation des modificateurs de portée

J’ai défini la variable $greeting dans la portée globale de la console comme étant « Hello, Jeff! ». J’ai ensuite exécuté le fichier script, qui a réaffecté la valeur à « Hello, World! » en utilisant le modificateur de portée $global:. Après avoir exécuté le script, la valeur de $greeting a été modifiée dans la portée globale de la console pour devenir la valeur du script.

Utilisation des portées dans un module PowerShell

Un module PowerShell est un ensemble de commandes, telles que des cmdlets ou des fonctions, qui ont des rôles ou des objectifs similaires. Le module ActiveDirectory pour Windows PowerShell en est un exemple ; il contient des commandes permettant de gérer les objets Active Directory.

Si vous créez vous-même un module, vous pouvez avoir besoin d’appeler la même variable dans différentes fonctions. En définissant les variables à l’aide de la portée script dans un module, celles-ci deviennent partageables entre les différentes fonctions du module.

Voici un exemple de fichier de module PowerShell (MyModule.psm1) qui contient deux fonctions, Get-Greeting et Set-Greeting :

  1. function Get-Greeting {
  2. if ($name) {
  3. $greeting = “Hello, $name!”
  4. }
  5. else {
  6. $greeting = “Hello, World!”
  7. }
  8. $greeting
  9. }
  10. function Set-GreetingName {
  11. param(
  12. [Parameter(Mandatory)]
  13. [string]
  14. $GreetingName
  15. )
  16. $name = $GreetingName
  17. }

Notez que les deux fonctions font référence à la variable $name. Toutefois, comme j’ai défini cette variable dans des fonctions distinctes, elle n’est étendue qu’à une fonction dans les deux cas. La définition de la variable $name dans la fonction Set-GreetingName n’affecte pas la variable $name dans la fonction Get-Greeting. Vous pouvez essayer vous-même en enregistrant ce code dans un fichier .psm1, en l’important à l’aide de la commande Import-Module, puis en renvoyant au nom de fichier du module.

La variable est étendue à la fonction

Même si je définis la variable $name au moyen de la fonction Set-GreetingName, cela n’affecte pas la variable $name dans la fonction Get-Greeting ; Chaque variable $name est étendue à sa propre fonction. Si je change la valeur dans une fonction, cela n’affecte pas l’autre fonction.

Si je veux que la variable soit accessible à toutes les fonctions du module, j’ajoute le modificateur $script: à la variable $name, comme ceci :

  1. function Get-Greeting {
  2. if ($script:name) {
  3. $greeting = “Hello, $script:name!”
  4. }
  5. else {
  6. $greeting = “Hello, World!”
  7. }
  8. $greeting
  9. }
  10. function Set-GreetingName {
  11. param(
  12. [Parameter(Mandatory)]
  13. [string]
  14. $GreetingName
  15. )
  16. $script:name = $GreetingName
  17. }

Si je réimporte le module à l’aide du paramètre -Force, je peux maintenant définir la valeur $name dans une fonction et la référencer dans une autre.

La variable est étendue au module

Notez que quand j’appelle la fonction Get-Greeting, le message par défaut s’affiche, car la variable $script:name n’a pas de valeur. Après avoir appelé la fonction Set-GreetingName, la fonction Get-Greeting affiche désormais une valeur différente selon le nom que j’ai transmis. C’est normal, car les deux fonctions font désormais appel à la même variable.

Bien que module de l’exemple soit simple, vous pouvez constater l’utilité de cette manœuvre. J’utilise cette fonctionnalité pour définir des informations d’identification API qu’utilisent plusieurs fonctions dans les modules que j’écris. Découvrez un exemple dans mon référentiel GitHub twilio-powershell-module.

Portée avec notation « dot sourcing »

Comme je l’ai montré dans les exemples ci-dessus, les scripts et les fonctions ont leur propre portée hors portée globale. Les modifications apportées aux variables affectent uniquement cette portée, à moins d’utiliser un modificateur de portée pour changer la portée de la variable.

Toutefois, vous pouvez incorporer la portée d’un script ou d’une fonction en utilisant la notation « dot sourcing ». Quand le script s’exécute dans la portée actuelle, toutes les variables de script sont disponibles dans la portée actuelle. Vous pouvez utiliser la notation « dot sourcing » en plaçant un point (.) et une espace avant le nom du script. Observez le fichier script et le code ci-dessous :

Utilisation de la notation « dot sourcing »

Initialement, la valeur de $greeting dans la portée globale de la console est vide ou nulle, et le fichier scopetest.ps1 définit la valeur de $greeting. En utilisant la notation « dot sourcing », le script reporte la valeur de la variable dans la portée parente. Vous pouvez également utiliser l’opérateur d’appel/esperluette (&) pour exécuter un script ou une fonction, et sa portée ne sera pas ajoutée à la portée actuelle.

Ressources complémentaires

Il est essentiel de comprendre la notion de portée dans PowerShell pour écrire des scripts, des modules et des fonctions. Vous pourriez rencontrer une variable de valeur inattendue, et cela pourrait être dû au fait que la variable hérite d’une autre portée. L’utilisation d’autres techniques telles que la portée des modules et la notation « dot sourcing » peut vous aider à développer des compétences précieuses pour votre « boîte à outils » PowerShell.

Pour plus d’informations sur l’écriture de scripts PowerShell, consultez le tutoriel d’écriture de scripts Windows PowerShell pour débutants de Jeff Petter.

Jeff Brown

Jeff Brown

Jeff Brown est un ingénieur en informatique Cloud, spécialisé dans les technologies Microsoft telles qu'Office 365, Teams, Azure et PowerShell.

 

Votre cybersécurité est-elle au cœur de votre infrastructure ?

Bénéficiez d'une évaluation personnalisée des risques auxquels sont exposées vos données, effectuée par des ingénieurs passionnés par la sécurité des données.