Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Note éditoriale
Important
La spécification du langage Windows PowerShell 3.0 a été publiée en décembre 2012 et est basée sur Windows PowerShell 3.0. Cette spécification ne reflète pas l’état actuel de PowerShell. Il n’existe aucun plan de mise à jour de cette documentation pour refléter l’état actuel. Cette documentation est présentée ici pour référence historique.
Le document de spécification est disponible en tant que document Microsoft Word à partir du Centre de téléchargement Microsoft à l’adresse : https://www.microsoft.com/download/details.aspx?id=36389 ce document Word a été converti pour présentation ici sur Microsoft Learn. Pendant la conversion, certaines modifications éditoriales ont été apportées pour prendre en charge la mise en forme de la plateforme Docs. Certaines fautes de frappe et erreurs mineures ont été corrigées.
11.1 Introduction
Comme indiqué dans §3.14, un module est une unité réutilisable autonome qui permet au code PowerShell d’être partitionné, organisé et abstrait. Un module peut contenir un ou plusieurs membres de module , qui sont des commandes (telles que des applets de commande et des fonctions) et des éléments (tels que des variables et des alias). Les noms de ces membres peuvent être maintenus privés pour le module, ou ils peuvent être exportés vers la session dans laquelle le module est importé.
Il existe trois types de modules différents: manifeste, script et binaire. Un module manifeste est un fichier qui contient des informations sur un module et contrôle certains aspects de l’utilisation de ce module. Un module de script est un fichier de script PowerShell avec une extension de fichier de .psm1 au lieu de .ps1. Un module binaire contient des types de classes qui définissent des applets de commande et des fournisseurs. Contrairement aux modules de script, les modules binaires sont écrits dans des langages compilés. Les modules binaires ne sont pas couverts par cette spécification.
Un module binaire est un assembly .NET (c’est-à-dire une DLL) qui a été compilé sur les bibliothèques PowerShell.
Les modules peuvent imbriquer; autrement dit, un module peut importer un autre module. Un module associé à des modules imbriqués est un module racine .
Quand une session PowerShell est créée, par défaut, aucun module n’est importé.
Lorsque les modules sont importés, le chemin de recherche utilisé pour les localiser est défini par la variable d’environnement PSModulePath.
Les applets de commande suivantes traitent des modules :
- Get-Module : identifie les modules qui ont été ou peuvent être importés
- Import-Module : ajoute un ou plusieurs modules à la session active (voir §11.4)
- Export-ModuleMember: identifie les membres du module à exporter
- Remove-Module: supprime un ou plusieurs modules de la session active (voir §11.5)
- New-Module : crée un module dynamique (voir §11.7)
11.2 Écriture d’un module de script
Un module de script est un fichier de script. Tenez compte du module de script suivant :
function Convert-CentigradeToFahrenheit ([double]$tempC) {
return ($tempC * (9.0 / 5.0)) + 32.0
}
New-Alias c2f Convert-CentigradeToFahrenheit
function Convert-FahrenheitToCentigrade ([double]$tempF) {
return ($tempF - 32.0) * (5.0 / 9.0)
}
New-Alias f2c Convert-FahrenheitToCentigrade
Export-ModuleMember -Function Convert-CentigradeToFahrenheit
Export-ModuleMember -Function Convert-FahrenheitToCentigrade
Export-ModuleMember -Alias c2f, f2c
Ce module contient deux fonctions, chacune ayant un alias. Par défaut, tous les noms de fonction et seuls les noms de fonction sont exportés. Toutefois, une fois que l’applet de commande Export-ModuleMember a été utilisée pour exporter quoi que ce soit, seules ces opérations exportées explicitement seront exportées. Une série de commandes et d’éléments peut être exportée dans un appel ou un certain nombre d’appels à cette applet de commande ; ces appels sont cumulatifs pour la session active.
11.3 Installation d’un module de script
Un module de script est défini dans un fichier de script, et les modules peuvent être stockés dans n’importe quel répertoire. La variable d’environnement PSModulePath pointe vers un ensemble de répertoires à rechercher lorsque les applets de commande liées au module recherchent des modules dont les noms n’incluent pas de chemin complet. Des chemins de recherche supplémentaires peuvent être fournis ; par exemple
$Env:PSModulePath = $Env:PSModulePath + ";<additional-path>"
Tous les chemins d’accès supplémentaires ajoutés affectent uniquement la session active.
Vous pouvez également spécifier un chemin complet lorsqu’un module est importé.
11.4 Importation d’un module de script
Avant que les ressources d’un module puissent être utilisées, ce module doit être importé dans la session active, à l’aide de l’applet de commande Import-Module.
Import-Module peut restreindre les ressources qu’elle importe réellement.
Lorsqu’un module est importé, son fichier de script est exécuté. Ce processus peut être configuré en définissant un ou plusieurs paramètres dans le fichier de script et en passant des arguments correspondants via le paramètre ArgumentList de Import-Module.
Considérez le script suivant qui utilise ces fonctions et alias définis dans §11.2:
Import-Module -Verbose « E :\Scripts\Modules\PSTest_Temperature »
"0 degrees C is " + (Convert-CentigradeToFahrenheit 0) + " degrees F"
"100 degrees C is " + (c2f 100) + " degrees F"
"32 degrees F is " + (Convert-FahrenheitToCentigrade 32) + " degrees C"
"212 degrees F is " + (f2c 212) + " degrees C"
L’importation d’un module provoque un conflit de noms lorsque les commandes ou les éléments du module ont les mêmes noms que les commandes ou les éléments de la session. Un conflit de noms entraîne un nom masqué ou remplacé. Le paramètre Préfixe de Import-Module peut être utilisé pour éviter les conflits d’affectation de noms. En outre, les paramètres d’alias , de cmdlet , de fonction et de variable peuvent limiter la sélection des commandes à importer, ce qui réduit les risques de conflit de noms.
Même si une commande est masquée, elle peut être exécutée en qualifier son nom avec le nom du module dans lequel elle provient. Par exemple, & M\F 100 appelle la fonction F dans le module Met lui passe l'argument 100.
Lorsque la session inclut des commandes du même type portant le même nom, telles que deux applets de commande portant le même nom, par défaut, elle exécute la commande la plus récente ajoutée.
Consultez §3.5.6 pour une discussion sur l’étendue liée aux modules.
11.5 Suppression d’un module de script
Un ou plusieurs modules peuvent être supprimés d’une session via l’applet de commande Remove-Module.
La suppression d’un module ne désinstalle pas le module.
Dans un module de script, il est possible de spécifier le code à exécuter avant la suppression de ce module, comme suit :
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { *on-removal-code* }
Manifestes de module 11.6
Comme indiqué dans §11.1, un module manifeste est un fichier qui contient des informations sur un module et contrôle certains aspects de l’utilisation de ce module.
Un module n’a pas besoin d’un manifeste correspondant, mais s’il le fait, ce manifeste porte le même nom que le module qu’il décrit, mais avec une extension de fichier .psd1.
Un manifeste contient un sous-ensemble limité de script PowerShell, qui retourne une table de hachage contenant un ensemble de clés. Ces clés et leurs valeurs spécifient les éléments de manifeste pour ce module. Autrement dit, ils décrivent le contenu et les attributs du module, définissent les prérequis et déterminent la façon dont les composants sont traités.
Essentiellement, un manifeste est un fichier de données ; Toutefois, il peut contenir des références aux types de données, à l’instruction if et aux opérateurs arithmétiques et de comparaison. (Les affectations, les définitions de fonction et les boucles ne sont pas autorisées.) Un manifeste dispose également d’un accès en lecture aux variables d’environnement et peut contenir des appels à l’applet de commande Join-Path, afin que les chemins d’accès puissent être construits.
Remarque
Remarque de l’éditeur : le document d’origine contient une liste de clés autorisées dans un fichier manifeste de module. Cette liste est obsolète et incomplète. Pour obtenir la liste complète des clés d’un manifeste de module, consultez New-ModuleManifest.
La seule clé requise est ModuleVersion.
Voici un exemple de manifeste simple :
@{
ModuleVersion = '1.0'
Author = 'John Doe'
RequiredModules = @()
FunctionsToExport = 'Set*','Get*','Process*'
}
La clé GUID a une valeur de string. Cela spécifie un IDENTIFICATEUR global unique (GUID) pour le module. Le GUID peut être utilisé pour distinguer les modules portant le même nom. Pour créer un GUID, appelez la méthode [guid]::NewGuid().
Modules dynamiques 11.7
Un module dynamique est un module créé en mémoire au moment de l’exécution par l’applet de commande New-Module; il n’est pas chargé à partir du disque. Prenons l’exemple suivant :
$sb = {
function Convert-CentigradeToFahrenheit ([double]$tempC) {
return ($tempC * (9.0 / 5.0)) + 32.0
}
New-Alias c2f Convert-CentigradeToFahrenheit
function Convert-FahrenheitToCentigrade ([double]$tempF) {
return ($tempF - 32.0) * (5.0 / 9.0)
}
New-Alias f2c Convert-FahrenheitToCentigrade
Export-ModuleMember -Function Convert-CentigradeToFahrenheit
Export-ModuleMember -Function Convert-FahrenheitToCentigrade
Export-ModuleMember -Alias c2f, f2c
}
New-Module -Name MyDynMod -ScriptBlock $sb
Convert-CentigradeToFahrenheit 100
c2f 100
Le bloc de script $sb définit le contenu du module, dans ce cas, deux fonctions et deux alias pour ces fonctions. Comme avec un module sur disque, seules les fonctions sont exportées par défaut. Par conséquent, Export-ModuleMember appels d’applets de commande existent pour exporter les fonctions et les alias.
Une fois New-Module exécuté, les quatre noms exportés sont disponibles pour utilisation dans la session, comme le montrent les appels à Convert-CentigradeToFahrenheit et c2f.
Comme tous les modules, les membres des modules dynamiques s'exécutent dans une étendue de module privée qui est un enfant de l'étendue globale.
Get-Module ne peut pas obtenir un module dynamique, mais Get-Command pouvez obtenir les membres exportés.
Pour rendre un module dynamique disponible pour Get-Module, diriger une commande New-Module vers Import-Module, ou diriger l’objet de module qui New-Module retourne, vers Import-Module. Cette action ajoute le module dynamique à la liste Get-Module, mais elle n’enregistre pas le module sur le disque ou le rend persistant.
11.8 Fermetures
Un module dynamique peut être utilisé pour créer une fermeture, une fonction avec des données attachées. Prenons l’exemple suivant :
function Get-NextID ([int]$StartValue = 1) {
$nextID = $StartValue
{
($Script:nextID++)
}.GetNewClosure()
}
$v1 = Get-NextID # get a scriptblock with $StartValue of 0
& $v1 # invoke Get-NextID getting back 1
& $v1 # invoke Get-NextID getting back 2
$v2 = Get-NextID 100 # get a scriptblock with $StartValue of 100
& $v2 # invoke Get-NextID getting back 100
& $v2 # invoke Get-NextID getting back 101
L’objectif ici est que Get-NextID renvoie l’ID suivant dans une séquence dont la valeur de départ peut être spécifiée. Toutefois, plusieurs séquences doivent être prises en charge, chacune avec son propre contexte $StartValue et $nextID. Cela est obtenu par l’appel à la méthode [scriptblock]::GetNewClosure (§4.3.7).
Chaque fois qu’une nouvelle fermeture est créée par GetNewClosure, un nouveau module dynamique est créé et les variables de l’étendue de l’appelant (dans ce cas, le bloc de script contenant l’incrément) sont copiées dans ce nouveau module. Pour vous assurer que le nextId défini à l’intérieur de la fonction parente (mais en dehors du bloc de script) est incrémenté, le préfixe d’étendue explicite Script : préfixe d’étendue est nécessaire.
Bien sûr, le bloc de script n’a pas besoin d’être une fonction nommée ; par exemple:
$v3 = & { # get a scriptblock with $StartValue of 200
param ([int]$StartValue = 1)
$nextID = $StartValue
{
($Script:nextID++)
}.GetNewClosure()
} 200
& $v3 # invoke script getting back 200
& $v3 # invoke script getting back 201