Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. PowerShell
  3. Création de modules
Extrait - PowerShell Fonctionnalités avancées (2e édition)
Extraits du livre
PowerShell Fonctionnalités avancées (2e édition)
1 avis
Revenir à la page d'achat du livre

Création de modules

Introduction

Le mot "module" fait généralement penser à "modulaire". On a l’image d’un élément de base, massif, à partir duquel gravitent d’autres éléments de plus petite taille qui viennent compléter ses fonctionnalités. Ces éléments peuvent être retirés, agrémentés, ajoutés, voire transférés.

images/02EXPIT01_Rel.png

Illustration de la modulalité sous PowerShell

Il en est ainsi des modules PowerShell, même si ces derniers sont plus que de simples ajouts. En effet, l’ensemble des commandes PowerShell, notamment les commandes de base, est contenu dans des modules. Les modules ont fait leur apparition avec PowerShell 2.0. Ils ont supplanté les snapins, apparus dans la première version de PowerShell. Les snapins sont encore utilisés, mais Microsoft conseille l’utilisation des modules, bien plus simples à mettre en place.

Les modules permettent d’organiser correctement le code conçu. Mais surtout, ils facilitent le partage du code avec des collègues, voire avec la communauté entière.

À l’heure où ces lignes sont écrites, Microsoft a recensé 11554 modules publiés sur sa plateforme de téléchargement PowerShell Gallery (voir le chapitre Gestion des modules et des packages). Cela peut donner...

Module dynamique

La seconde possibilité pour créer un module est la commande New-Module. Elle crée un module dit dynamique. Il est chargé en mémoire et existe le temps de la session PowerShell. Cela signifie qu’il n’est pas écrit sur le disque, et donc invisible via la commande Get-Module (nous verrons plus loin qu’il existe un moyen de le faire apparaître). Les fonctions créées restent toutefois visibles par la commande Get-Command.

Arguments de la commande New-Module :

Paramètre

Description

ArgumentList

Indique un tableau de valeurs à passer au paramètre -ScriptBlock.

AsCustomObject

Renvoie le module sous forme de CustomObject lors de sa création. Il peut ainsi être assigné dans une variable. Les fonctions ou cmdlets exportées se présentent sous forme de méthode de cet objet.

Cmdlet

Filtre les cmdlets qui sont exportées du module. Pour cela, il est nécessaire d’indiquer une liste avec le nom des cmdlets à exporter. Par défaut, l’ensemble des cmdlets est exporté. Les wildcards sont supportées.

Function

Filtre les fonctions qui sont exportées à partir du -ScriptBlock. Même syntaxe que le paramètre -Cmdlet.

Name

Indique un nom de module. Étant donné que cela est obligatoire, si la valeur est nulle ou vide, PowerShell génère un nom de configuration aléatoire. Son nom débute alors par "_DynamicModule". Il sera suivi d’un GUID.

ReturnResult

Retourne la sortie du bloc de script, en plus de la création du module.

ScriptBlock

Indique le contenu du module dynamique. Ce bloc est délimité par des accolades. Les fonctions doivent être séparées...

Module binaire

Les modules binaires sont un type de modules assez spécifiques. Ils contiennent du code compilé à partir d’un langage .NET. On peut citer en exemple C#, ainsi que VB.NET, ou encore ASP.NET. Attention toutefois, même si un module binaire est proche d’un snapin par sa conception, ils sont tous les deux différents. L’installation d’un snapin nécessite des droits administrateur, ce qui n’est pas le cas d’un module binaire. Une simple copie suffit, tout comme les modules script (sauf si l’on copie le module dans un dossier nécessitant une élévation de privilèges, comme Program Files).

La conception de cmdlets à travers un langage .NET est très intéressante. Elle permet d’avoir un temps d’exécution supérieur comparé aux fonctions PowerShell. Toutefois, leur découverte ne relève pas de ce livre. En effet, cela s’adresse à des développeurs. Mais de manière générale, il est fortement conseillé de s’intéresser de près au framework .NET, surtout si l’on cherche constamment la performance dans les scripts et fonctions PowerShell. Le .NET est extrêmement riche, avec des classes d’objets qui font gagner un temps non négligeable.

Module script

Les modules de type script sont les plus connus de par leur facilité et rapidité de création. Ils sont également simples à déployer, et plus faciles d’accès.

La création d’un module est relativement simple. Il peut d’ailleurs être stocké à différents endroits. Pour cela, il faut se référer au contenu de la variable d’environnement $Env:PSModulePath. Si le module créé n’est pas contenu dans un des répertoires de cette variable, alors il ne sera pas découvert automatiquement par PowerShell. Par ailleurs, il est tout à fait possible de modifier cette variable pour y ajouter ses propres chemins d’accès.

Attention : si vous modifiez cette variable, il est très important de ne pas supprimer les valeurs par défaut qui sont déjà présentes.

Si l’on décide de se passer de $Env:PSModulePath, il est toujours possible d’importer le module manuellement, en indiquant chemin d’accès complet à l’applet de commande Import-Module. Pour connaître le contenu de la variable $Env:PSModulePath :

PS > $Env:PSModulePath.Split(';') 
C:\Users\Nicol\Documents\WindowsPowerShell\Modules 
C:\Program Files\WindowsPowerShell\Modules 
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules 

Une fois l’emplacement trouvé, il suffit de créer un dossier qui porte le nom du module, puis un fichier PSM1. Il doit porter le même nom que le dossier. Ce fichier va contenir le code PowerShell, voire faire appel à des scripts PS1.

Exemple de création du module

PS > New-Item -Path $Home\Documents\WindowsPowerShell\Modules ` 
            -Name MyModuleTools -Type directory 
 
PS > New-Item -Name MyModuleTools.psm1 -Type File ` 
-Path $Home\Documents\WindowsPowerShell\Modules\MyModuleTools 

Pour le moment, le module est vide. On va donc lui ajouter quelques fonctions utiles. Il est également intéressant d’y inclure une fonction qui fait appel à une seconde fonction, assez longue, utilisée régulièrement.

Les linuxiens sous Bash sont habitués à créer des alias pour appliquer un comportement par défaut à...

Manifeste de module

Le manifeste d’un module est un élément important si l’on souhaite partager son travail. Il s’agit d’un fichier au format PSD1. Il est formaté sous forme de hashtable et chaque champ détient les métadonnées concernant le module. Ces métadonnées regroupent un certain nombre d’éléments sur le module, tels que le nom de l’auteur, le numéro de version, les notes de versions, les différents fichiers à charger, ou encore les différents prérequis du module. Cette dernière section n’est d’ailleurs pas qu’informative. Elle a un impact important lors du chargement du module.

Si une version minimum de PowerShell est renseignée dans le manifeste, on ne peut pas utiliser le module dès lors que la version de PowerShell exécutée par le système est antérieure à celle indiquée.

Pour les manifestes, PowerShell dispose de deux cmdlets, New-ModuleManifest et Test-ModuleManifest. Les noms sont assez explicites : la première crée un manifeste, la seconde le teste.

1. Création du manifeste

La cmdlet New-ModuleManifest dispose d’un grand nombre de paramètres. Cela vient du fait que chaque paramètre référence un champ de la hashtable du fichier manifeste. Seul le paramètre -Path est obligatoire. En l’absence d’autres paramètres, le fichier créé est prérempli avec l’ensemble des champs à renseigner.

Paramètres de la cmdlet :

Paramètre

Description

AliasToExport

Liste des alias à exporter pour les rendre utilisables par l’utilisateur.

Author

Auteur du module.

ClrVersion

Version du CLR utilisé par le module. Cette information est contenue dans la variable $PSVersionTable.

CmdletsToExport

Liste des cmdlets à exporter pour les rendre utilisables par l’utilisateur.

CompanyName

Nom de la société de l’auteur.

Copyright

Copyright régissant le module.

DefaultCommandPrefix

Préfixe donné à chaque commande. Ce préfixe permet d’éviter les conflits avec des modules ayant des commandes portant le même nom. Le préfixe est situé avant le nom de la commande, et non avant le verbe.

Description...

Exportation des membres d’un module

1. La commande Export-ModuleMember

Par défaut, avec ou sans manifeste, un module contenu dans un fichier PSM1 exporte l’ensemble de ses fonctions. Toutefois, les variables et alias ne sont pas exportés, malgré la présence des champs VariablesToExport et AliasToExport dans le manifeste.

Pour cette raison, il peut être intéressant d’utiliser la cmdlet Export-ModuleMember. Elle ne peut être utilisée que dans deux cas : dans un module dynamique ou dans un fichier PSM1. La commande ne dispose que de quatre paramètres : -Function, -Alias-Cmdlet, -Variable. Chaque paramètre accepte un tableau de chaînes de caractères ([String[]]).

À partir du moment où la commande Export-ModuleMember est utilisée, il est obligatoire que chaque élément que l’on souhaite exporter y soit présent. Soyez donc attentif lorsque vous ajoutez un élément à votre module.

Exemple de déclaration

Function Get-PSSerialNumber { 
    (Get-WMIObject -Class Win32_Bios).SerialNumber 
} 
 
Function Get-PSFolderSize { 
    Param( 
           [ValidateScript({Test-Path $_})] 
           [String]$Path 
    ) 
    (Get-ChildItem -Path $Path -Recurse -File | ` 
    Measure-Object -Property Length -Sum ).Sum /1MB 
} 
Set-Alias -Name gpsn -Value 'Get-PSSerialNumber' 
$ScriptAuthor = 'Nicolas Baudin' 
 
Export-ModuleMember -Function `  
    'Get-PSFolderSize','Get-PSSerialNumber' 
Export-ModuleMember -Variable 'ScriptAuthor' -Alias 'gpsn' 

Après l’importation du module, il est possible d’utiliser les alias, les fonctions, mais également d’appeler la variable $ScriptAuthor.

2. Comportement particulier

Il existe différentes manières d’exporter les membres d’un module. Dans cette section, chaque membre va être étudié au cas par cas.

Il est possible que le comportement diffère en fonction de la version...

Structure multifichier

Lors du maintien et de l’évolution d’un module, sa structure est un point important. S’il est très mal organisé, personne ne voudra travailler dessus, voir l’utiliser. Au contraire, si la structure est claire et définie, on aura plaisir à participer à son cycle de vie.

Il n’existe pas vraiment de structure conventionnelle. Le plus important est de documenter et de renseigner l’utilité de chaque dossier et de chaque fichier. Le travail d’un relecteur ou d’un contributeur sera ainsi facilité.

La structure présentée ici est un exemple. Elle n’est pas parfaite, mais a de gros avantages pour faciliter le maintien d’un module.

Structure hiérarchique

$Env:PSModulePath 
  └─<Version> 
    └─<Nom du module> 
      ├─Public 
         └─<Nom Script>.ps1 
      ├─Private 
         └─<Nom Script>.ps1 
      ├─<Manifeste du module>.psd1 
      ├─<Fichier principal>.psm1 
      └─<other...

Passer au Build avec Sampler

Dans la philosophie de développement d’un package, on retrouve généralement une phase de construction (build). Celle-ci prend le code brut, puis l’organise pour donner le package qui sera ensuite déployé. Dans cette phase de build, on retrouve souvent une compilation de code.

Dans notre cas, il s’agit d’un module. Le but est de pouvoir joindre la structure vue précédemment, et l’avantage d’un fichier PSM1 complet et performant. Pour cela, on part d’une structure multifichier, semblable à celle présentée dans la section précédente, pour le développement du module. Puis on utilise un outil de build afin d’arriver à un module construit sur un seul PSM1.

L’outil présenté ici est Sampler. Il s’agit d’un module communautaire développé par Gael Colas. Il en existe d’autres, notamment Stucco.

La motivation première de Gael pour concevoir ce module a été en priorité alimentée par les ressources DSC. En effet, Gael est l’un des piliers de la DSC Community et il souhaitait standardiser l’écriture des ressources DSC en basant leur développement sur une structure et des process de validation et de déploiement communs.

Sampler se base sur plusieurs modules pour construire un module de A à Z. En voici quelques-uns :

  • Plaster : génère la structure du nouveau module en se basant sur des modèles.

  • InvokeBuild : organise un ensemble d’actions sous forme de task.

  • PSDepend : gère les dépendances pour la construction du module.

  • PSDeploy : gère le déploiement du module sur une galerie, interne ou externe.

Le module Sampler est disponible sur la PowerShell Gallery. L’installation du module s’opère grâce au module PowerShellGet. Pour plus d’informations sur l’utilisation de ce dernier, référez-vous au chapitre Gestion des modules et des packages.

PS > Install-Module Sampler 

1. Création d’un module simple

Sampler propose plusieurs modèles de structures pour créer un module, en voici la liste :

  • SimpleModule : projet de module simple avec une structure minimale et le process d’automatisation....