Scopes dans PowerShell –
Dans de nombreux langages de programmation, il existe le concept de portée. Défini comme quelles variables et fonctions sont disponibles dans quel contexte. Un exemple est si une variable est disponible pour chaque fonction dans un script PowerShell, ou juste une seule fonction définie. Les étendues PowerShell englobent plusieurs étendues différentes qui peuvent être utilisées, telles que les étendues globales, locales ou de script.
Sommaire
Quelles sont les étendues PowerShell?
Comme mentionné dans l’introduction, il existe plusieurs portées principales. Ceux-ci sont globaux, locaux et de script et indiquent à PowerShell quelles variables et fonctions sont disponibles dans quel contexte. Lorsque vous faites référence à des étendues, vous utilisez généralement des préfixes d’étendue pour atteindre des variables en dehors de l’étendue locale actuelle. Ceci est plus facile à comprendre à travers des exemples.
Portée mondiale
La portée globale signifie qu’une variable sera disponible pour toutes les fonctions et commandes quel que soit leur emplacement, comme $MyVar = $True
ou $Global:MyVar = $True
. Lors du lancement de PowerShell, toutes les variables initiales ont une portée globale. S’il n’y a pas d’étendues enfants, global est identique à l’étendue locale et script jusqu’à ce que les étendues enfants existent.
# This is in the Global scope
$MyVar = $True
Function Test-VariableScope {
# When a variable is not found in the current scope, look up till it is found
Write-Host "Global Scope: $MyVar"
# Redefine the variable in the Local scope
$MyVar = $False
Write-Host "Local Scope: $MyVar"
Write-Host "Global Scope: $($Global:MyVar)"
}
Test-VariableScope
# Since the Locally scoped variable does not exist anymore, return the Global scope
Write-Host "Global Scope: $MyVar"
Portée locale
L’étendue actuelle est toujours locale, et donc l’étendue par défaut également. Lorsqu’aucun modificateur de portée n’est utilisé sur une variable, la portée est locale telle que $MyVar = $True
. L’étendue locale peut être difficile à comprendre car cette étendue est relative à l’emplacement actuel et une variable locale peut être dans différentes étendues en même temps.
# This is in the Local scope (and Global scope since at root of script)
$MyVar = $True
Write-Host "Local Scope: $MyVar"
Write-Host "Local Scope Explicit: $($Local:MyVar)"
Function Test-VariableScope {
# This variable is in the Local scope relative to Test-VariableScope
$MyVar = $False
Write-Host "Local Scope: $MyVar"
Write-Host "Local Scope (Explicit): $($Local:MyVar)"
}
Test-VariableScope
# This variable is back to the local scope initially defined
Write-Host "Local Scope: $MyVar"
Write-Host "Local Scope Explicit: $($Local:MyVar)"
Lorsque vous dotez un script, tel que
. my-script.ps1
, vous allez ajouter la sortie entière de ce script à la portée locale!
Portée du script
Enfin, la portée du script est un peu plus compliquée. Il s’agit de la portée du fichier de script ancêtre le plus proche ou de la portée globale si elle n’est pas exécutée dans un fichier de script tel que $script:var = $true
. Les portées Global, Script et Local sont les mêmes pour le $MyVar = $True
variable lorsqu’elle est utilisée dans un seul script, et même dans des fonctions.
# This is in the Script scope including Script and Local scope
$MyVar = $True
Write-Host "Script Scope: $($Script:MyVar)"
Function Test-VariableScope {
# This variable is in the Local scope relative to Test-VariableScope
$MyVar = $False
# The Script scope references the same as $MyVar variable initially defined
Write-Host "Script Scope: $($Script:MyVar)"
}
Test-VariableScope
# This variable is back to the Script scope initially defined
Write-Host "Script Scope: $($Script:MyVar)"
Contrairement au dot-sourcing, un script qui ajoute tout à la portée locale, en utilisant le &
L’opérateur d’appel exécutera le script, mais laissera tout dans la portée du script qui est relative au script lui-même.
Quelles sont les options Privé, Utilisation, Flux de travail et AllScope?
Outre les étendues générales, il existe plusieurs options qui peuvent modifier la visibilité ou la disponibilité des variables. Alors, quelles sont ces différentes options avec des portées?
Le modificateur d’étendue privée
Lorsque vous définissez une variable ou un alias comme privé, la variable ou l’alias n’est visible et modifiable qu’à partir de ce contexte. Comme vous pouvez le voir dans l’exemple ci-dessous, la version privée du
Remove-Variable TestVar
Remove-Variable TestVar2
Remove-Variable TestVar3
# Two ways to create a private variable, note that this is an Option and not a Scope (applied to a scoped variable)
New-Variable -Name 'TestVar' -Value $True -Scope 'Global' -Option 'Private'
$Private:TestVar2 = $True
Write-Host "Global Scope (TestVar): $TestVar"
Write-Host "Global Scope (TestVar2): $TestVar"
$TestVar3 = $True
Function Test-Function {
# Since the first two variables are private they are not seen
Write-Host "Local Scope (TestVar): $TestVar"
Write-Host "Local Scope (TestVar2): $TestVar2"
# TestVar3 does not exist locally so PowerShell looks up and finds a non-Private variable in Global
Write-Host "Local Scope (TestVar3): $TestVar3"
}
Test-Function
Quel est le modificateur Using?
Il s’agit d’une variable spéciale utilisée par les applets de commande et les constructions Invoke-Command
, Start-Job
, Start-ThreadJob
, ou ForEach-Object -Parallel
. Cela ne fonctionnera qu’avec Invoke-Command
lorsqu’il est exécuté sur un ordinateur distant, par exemple avec le ComputerName
paramètre.
# Normally the LocalCSVData variable will not be available to the scriptblock running on the remote computer without the Using modifier.
$LocalCSVData = Import-CSV -Path 'mydata.csv'
Invoke-Command -ComputerName 'RemoteComputer' -ScriptBlock {
$Using:LocalCSVData | ForEach-Object {
...do something...
}
}
Workflow et AllScope
Bien que beaucoup moins utilisé, il existe deux modificateurs supplémentaires. le Workflow
Le modificateur est utilisé pour référencer des variables dans un flux de travail PowerShell (non disponible dans PowerShell Core / 7). le AllScope
Le modificateur rendra une variable disponible dans toutes les portées. Cela signifie également que si la variable est modifiée dans une étendue enfant, elle se reflétera dans les étendues racine. C’est une façon d’éviter d’avoir à préfixer une variable avec global lorsque vous essayez de la référencer dans les étendues enfants.
Conclusion
Les portées sont utiles pour limiter la visibilité et la disponibilité des variables, des fonctions et des alias. Les étendues peuvent également être gênantes lorsque la portée d’une variable n’est pas claire. Espérons que cet article vous explique comment les étendues sont utilisées dans PowerShell et ce que vous pouvez en faire!