Comment les étendues affectent-elles les scripts PowerShell

Table des matières:

Comment les étendues affectent-elles les scripts PowerShell
Comment les étendues affectent-elles les scripts PowerShell

Vidéo: Comment les étendues affectent-elles les scripts PowerShell

Vidéo: Comment les étendues affectent-elles les scripts PowerShell
Vidéo: MINUTEUR d'APPLICATIONS, comment voir le temps d'utilisation et d'interruptions sur son téléphone - YouTube 2024, Avril
Anonim
Dans les scripts de traitement par lots, les modifications apportées aux variables d'environnement ont un impact global sur la session en cours par défaut. Pour PowerShell, l’inverse est vrai, car les étendues servent à isoler les modifications d’un script. Nous étudierons ici l’impact des étendues sur les scripts PowerShell et la manière de travailler avec et autour d’eux.
Dans les scripts de traitement par lots, les modifications apportées aux variables d'environnement ont un impact global sur la session en cours par défaut. Pour PowerShell, l’inverse est vrai, car les étendues servent à isoler les modifications d’un script. Nous étudierons ici l’impact des étendues sur les scripts PowerShell et la manière de travailler avec et autour d’eux.

Qu'est-ce qu'une portée?

Dans PowerShell, une «étendue» fait référence à l'environnement actuel dans lequel un script ou un interpréteur de commandes fonctionne. Les étendues servent à protéger certains objets de l'environnement contre les modifications non intentionnelles effectuées par des scripts ou des fonctions. En particulier, les éléments suivants sont protégés contre les modifications par des commandes exécutées à partir d'une autre étendue, sauf spécification contraire par les paramètres de ces commandes:

  • Variables
  • Alias
  • Les fonctions
  • Disques PowerShell (PSDrives)

De nouvelles étendues sont créées chaque fois que vous exécutez un script ou une fonction, ou lorsque vous créez une nouvelle session ou une nouvelle instance de PowerShell. Les étendues créées en exécutant des scripts et des fonctions ont une relation «parent / enfant» avec la portée à partir de laquelle elles ont été créées. Il y a quelques domaines qui ont une signification particulière, et qui sont accessibles par leur nom:

  • le Global scope est l'étendue créée au démarrage de PowerShell. Il inclut les variables, alias, fonctions et lecteurs PSDr intégrés à PowerShell, ainsi que ceux créés par votre profil PowerShell.
  • le Local la portée fait référence à quelle que soit la portée actuelle. Lorsque vous démarrez PowerShell, il fait référence à la portée globale. Dans un script, il s'agit de la portée du script, etc.
  • le Scénario la portée est créée lors de l'exécution d'un script. Les seules commandes qui fonctionnent dans cette étendue sont celles qui sont dans le script.
  • Privé Des étendues peuvent être définies dans l’étendue actuelle pour empêcher les commandes d’autres étendues de lire ou de modifier des éléments auxquels elles auraient sinon accès.

Les portées peuvent également être désignées par un numéro dans certaines commandes, la portée actuelle étant appelée zéro et ses ancêtres étant référencés par des entiers croissants. Par exemple, dans un script exécuté à partir de la portée globale, la portée du script serait 0 et la portée globale, à 1. Une portée encore imbriquée dans la portée du script, telle qu'une fonction, ferait référence à la portée globale en tant que 2 Les nombres négatifs ne fonctionneront cependant pas pour faire référence aux portées des enfants - la raison en sera évidente dans un instant.

Comment les scopes affectent les commandes

Comme mentionné précédemment, les commandes exécutées dans une portée n'affecteront pas les tâches d'une autre portée, à moins d'indication contraire. Par exemple, si $ MyVar existe dans la portée globale et si un script exécute une commande pour définir la valeur différente de $ MyVar, la version globale de $ MyVar restera inchangée tant qu'une copie de $ MyVar sera placée dans la portée du script avec la nouvelle. valeur. Si $ MyVar n’existe pas, un script le créera par défaut dans la portée du script - pas dans la portée globale. Il est important de se rappeler que vous en apprendrez plus sur la relation parent / enfant réelle entre les portées.

La relation parent / enfant des portées dans PowerShell est à sens unique. Les commandes peuvent voir, et éventuellement modifier, la portée actuelle, son parent et toutes les portées supérieures. Cependant, ils ne peuvent pas voir ou modifier les choses chez les enfants de la portée actuelle. En effet, une fois que vous avez intégré une étendue parent, celle-ci a déjà été détruite car elle remplit sa fonction. Par exemple, pourquoi devriez-vous voir ou modifier une variable dans la portée du script, à partir de la portée globale, une fois le script terminé? Il existe de nombreux cas dans lesquels vous avez besoin que les modifications d’un script ou d’une fonction persistent au-delà de son achèvement, mais il n’y a pas beaucoup de cas où vous auriez besoin de modifier des objets dans la portée du script ou de la fonction avant ou après son exécution. (Habituellement, de telles choses seront traitées dans le script ou la fonction elle-même.)

Bien sûr, quelles sont les règles sans exceptions? Les étendues privées constituent une exception à ce qui précède. Les objets dans les étendues privées ne sont accessibles qu'aux commandes exécutées dans l'étendue à partir de laquelle ils ont été créés. Une autre exception importante concerne les éléments dotés de la propriété AllScope. Ce sont des variables spéciales et des alias pour lesquels une modification d'une portée affectera toutes les portées. Les commandes suivantes vous montreront quelles variables et quels alias ont la propriété AllScope:

Get-Variable | Where-Object {$_.Options -match 'AllScope'} Get-Alias | Where-Object {$_.Options -match 'AllScope')

Scopes en action

Pour notre premier aperçu des portées en action, nous allons commencer par une session PowerShell où la variable $ MyVar a été définie sur une chaîne, "Je suis une variable globale!", À partir de la ligne de commande. Ensuite, le script suivant sera exécuté à partir d'un fichier appelé Scope-Demo.ps1:

Function FunctionScope { 'Changing $MyVar with a function.' $MyVar = 'I got set by a function!' 'MyVar says $MyVar' } '' 'Checking current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' '' FunctionScope '' 'Checking final value of MyVar before script exit.' 'MyVar says $MyVar' ''

Si les scripts PowerShell fonctionnent de la même manière que les scripts de traitement par lots, nous nous attendons à ce que la valeur de $ MyVar (ou% MyVar% dans la syntaxe de traitement par lots) change de "Je suis une variable globale!" À "Je suis défini par un script!" et enfin à «Je me suis fixé par une fonction!» où elle resterait jusqu'à ce qu'elle soit explicitement modifiée à nouveau ou que la session soit terminée. Cependant, voyez ce qui se passe réellement ici lorsque nous parcourons chacune des portées - en particulier, une fois que la fonction FunctionScope a terminé son travail et que nous vérifions à nouveau la variable à partir de la portée Script et, plus tard, globale.

Comme vous pouvez le constater, la variable a semblé changer au fur et à mesure de notre progression dans le script car, jusqu'à ce que la fonction FunctionScope soit terminée, nous vérifiions la variable dans la même étendue que celle modifiée précédemment. Une fois que FunctionScope a été terminé, nous sommes revenus à la portée du script où $ MyVar n'a pas été touché par la fonction. Ensuite, lorsque le script s'est terminé, nous sommes revenus dans la portée globale, où il n'avait pas été modifié du tout.
Comme vous pouvez le constater, la variable a semblé changer au fur et à mesure de notre progression dans le script car, jusqu'à ce que la fonction FunctionScope soit terminée, nous vérifiions la variable dans la même étendue que celle modifiée précédemment. Une fois que FunctionScope a été terminé, nous sommes revenus à la portée du script où $ MyVar n'a pas été touché par la fonction. Ensuite, lorsque le script s'est terminé, nous sommes revenus dans la portée globale, où il n'avait pas été modifié du tout.

Atteindre en dehors de la portée locale

C’est donc très bien pour vous aider à ne pas appliquer accidentellement des modifications à l’environnement au-delà de vos scripts et de vos fonctions, mais qu’en est-il si vous souhaitez réellement apporter de telles modifications? Il existe une syntaxe spéciale et assez simple pour créer et modifier des objets au-delà de la portée locale. Vous venez de mettre le nom de la portée au début du nom de la variable et de placer deux points entre le nom de la portée et le nom de la variable. Comme ça:

$global:MyVar $script:MyVar $local:MyVar

Vous pouvez utiliser ces modificateurs lors de la visualisation et de la définition de variables. Voyons ce qui se passe avec ce script de démonstration:

Function FunctionScope { '' 'Changing $MyVar in the local function scope…' $local:MyVar = 'This is MyVar in the function's local scope.' 'Changing $MyVar in the script scope…' $script:MyVar = 'MyVar used to be set by a script. Now set by a function.' 'Changing $MyVar in the global scope…' $global:MyVar = 'MyVar was set in the global scope. Now set by a function.' '' 'Checking $MyVar in each scope…' 'Local: $local:MyVar' 'Script: $script:MyVar' 'Global: $global:MyVar' '' } '' 'Getting current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' FunctionScope 'Checking $MyVar from script scope before exit.' 'MyVar says $MyVar' ''

Comme précédemment, nous allons commencer par définir la variable dans la portée globale et terminer par la vérification du résultat final de la portée globale.

Vous pouvez voir ici que FunctionScope a été en mesure de modifier la variable dans la portée du script et de conserver les modifications après son achèvement. En outre, la modification de la variable dans la portée globale a persisté même après la fin du script. Cela peut être particulièrement utile si vous devez modifier de manière répétée les variables dans un script ou dans la portée globale, en utilisant le même code - vous venez de définir une fonction ou un script écrit pour modifier la variable où et comment vous en avez besoin. fait, et appelez-le chaque fois que ces changements sont nécessaires.
Vous pouvez voir ici que FunctionScope a été en mesure de modifier la variable dans la portée du script et de conserver les modifications après son achèvement. En outre, la modification de la variable dans la portée globale a persisté même après la fin du script. Cela peut être particulièrement utile si vous devez modifier de manière répétée les variables dans un script ou dans la portée globale, en utilisant le même code - vous venez de définir une fonction ou un script écrit pour modifier la variable où et comment vous en avez besoin. fait, et appelez-le chaque fois que ces changements sont nécessaires.

Comme mentionné précédemment, les numéros d'étendue peuvent également être utilisés dans certaines commandes pour modifier la variable à différents niveaux par rapport à l'étendue locale. Voici le même script utilisé dans le deuxième exemple ci-dessus, mais avec la fonction modifiée pour utiliser les commandes Get-Variable et Set-Variable avec des numéros d'étendue au lieu de référencer directement la variable avec des étendues nommées:

Function FunctionScope { '' 'Changing $MyVar in scope 0, relative to FunctionScope…' Set-Variable MyVar 'This is MyVar in the function's scope 0.' –Scope 0 'Changing $MyVar in scope 1, relative to FunctionScope…' Set-Variable MyVar 'MyVar was changed in scope 1, from a function.' –Scope 1 'Changing $MyVar in scope 2, relative to Functionscope…' Set-Variable MyVar 'MyVar was changed in scope 2, from a function.' –Scope 2 '' 'Checking $MyVar in each scope…' ‘Scope 0:’ Get-Variable MyVar –Scope 0 –ValueOnly ‘Scope 1:’ Get-Variable MyVar –Scope 1 –ValueOnly ‘Scope 2:’ Get-Variable MyVar –Scope 2 –ValueOnly '' } '' 'Getting current value of $MyVar.' 'MyVar says $MyVar' '' 'Changing $MyVar by script.' $MyVar = 'I got set by a script!' 'MyVar says $MyVar' FunctionScope 'Checking $MyVar from script scope before exit.' 'MyVar says $MyVar' ''

Image
Image

Comme auparavant, nous pouvons voir ici comment les commandes d'une portée peuvent modifier des objets dans sa portée parente.

Information additionnelle

Il y a encore beaucoup plus de choses qui peuvent être faites avec des oscilloscopes que ce que peut contenir cet article. Les portées affectent plus que des variables, et il reste encore beaucoup à apprendre sur les portées privées et les variables AllScope. Pour plus d'informations utiles, vous pouvez exécuter la commande suivante à partir de PowerShell:

Get-Help about_scopes

Le même fichier d'aide est également disponible sur TechNet.

Portée crédit image: spadassin sur openclipart

Conseillé: