Agence web » Actualités du digital » Scopes dans PowerShell –

Scopes dans PowerShell –

Logo 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.

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!

★★★★★