Share via


Windows PowerShell : le cycle de vie d'une fonction avancée

Fonctions avancées de Windows PowerShell — appelé applets de commande de Script — peut être un peu déroutant, mais Voici un moyen pour diriger leurs fonctions de configuration et de nettoyage.

Don Jones

Il y a eu un point de confusion pour un certain nombre d'étudiants dans certains de mes classes Windows PowerShell sur site en cours. J'espère qu'exploration plus en détail ici vous aide à une confusion pour vous de déroulement. La rubrique est de fonctions avancées de Windows PowerShell, appelé informelle les applets de commande de script. Le modèle pour ce type de fonction ressemble à ceci :

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN {} PROCESS {} END {} }

Il existe quelques aspects confus pour ces applets de commande. Par exemple, dans celle-ci, il est un paramètre d'entrée défini appelé Nom_Ordinateur. Cela peut accepter l'entrée à partir du pipeline. Cela signifie que vous pouvez appeler cette fonction de deux manières distinctes. Tout d'abord, vous pouvez avoir transmis dans, les chaînes telles qu'à partir d'un fichier texte qui contient un nom d'ordinateur par ligne :

Get-Content names.txt | Do-Something

Vous pouvez aussi tout simplement avoir une ou plusieurs noms d'ordinateur transmis directement au paramètre, sans utiliser le pipeline du tout :

Do-Something –computername SERVER1,SERVER2

Dans le premier exemple, bloc de début de la fonction exécute tout d'abord. Ensuite, le bloc PROCESS s'exécute une fois pour chaque nom d'ordinateur transmis. La variable de Nom_Ordinateur $ contient uniquement un nom d'ordinateur à la fois. Enfin, une fois qu'ils sont tous traités, le bloc END s'exécute une fois.

Dans le deuxième exemple, les blocs BEGIN et END ne jamais exécutent. Le bloc de processus s'exécute qu'une seule fois et Nom_Ordinateur $ contient tous les noms qui a été passée au paramètre.

Cette différence de comportement extrême peut rendre plus difficile effectuer l'installation et les tâches de nettoyage qui s'exécutent dans les deux situations. Il peut également provoquer la confusion sur le traitement avec les paramètres de Nom_Ordinateur $. Dans le premier exemple il uniquement contient une valeur à la fois, alors que dans la seconde, il contiendra une ou plusieurs valeurs, selon ce qui a été indiqué pour le paramètre-ComputerName. Vous pouvez résoudre le problème de Nom_Ordinateur $ en plaçant simplement une boucle ForEach dans le bloc de processus :

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN {} PROCESS { Foreach ($computer in $computername) { # use $computer here } } END {} }

Cette technique garantit que la variable d'ordinateur $ contiendra uniquement un nom d'ordinateur à la fois, pourquoi il est préférable de travailler avec qui, au lieu de $NomOrdinateur.

La configuration et nettoyage est un peu plus complexe. Vous ne souhaitez pas effectuer la configuration directement dans le bloc PROCESS. Ce bloc peut exécuter plusieurs fois lorsque les objets sont transmis. D'autre part, vous ne pouvez pas placer le programme d'installation directement dans le bloc BEGIN. Qui ne fonctionne pas si rien n'est transmis. Il existe évidemment un grand nombre de façons que vous pourriez cette situation, mais cela semble être le meilleur :

Function Do-Something { [CmdletBinding()] param( [Parameter(Mandatory=$True, ValueFromPipeline=$True)] [string[]]$computername ) BEGIN { $setup_done = $false function DoSomethingSetup { set-variable -name setup_done -value $true -scope 1 } DoSomethingSetup } PROCESS { if (-not $setup_done) { DoSomethingSetup } Foreach ($computer in $computername) { # use $computer here } } }

Il tire parti du fait que les blocs de début et de fin, processus de tous les partagent une portée commune, ce qui signifie qu'ils partagent les mêmes variables. En configurant une variable comme un indicateur, vous pouvez être sûr du contenu de la clé du bloc BEGIN — ma fonction DoSomethingSetup — appelé qu'une seule fois.

Avis de « DoSomethingSetup » fonction doit utiliser une technique spéciale pour définir l'indicateur sur $True une fois vous avez terminé les tâches de configuration. Dans la mesure où il s'agit d'une fonction, DoSomethingSetup a sa propre portée. Il est normalement Impossible de modifier la valeur d'une variable à partir d'en dehors de cette étendue. Vous pouvez modifier explicitement la variable nécessaire à l'aide de l'applet de commande Variable définie.

L'exécution de la même chose pour les tâches de nettoyage est un peu plus difficile. Dans le premier exemple, dans lequel les objets sont en cours transmis à-quelque chose, le bloc END s'exécute. Vous pouvez simplement placer vos tâches de nettoyage il. Toutefois, dans le deuxième exemple où rien n'est transmis, fin s'exécutera jamais. Le bloc PROCESS s'exécute qu'une seule fois, afin qu'il ne sont pas nécessairement « connaître » que le bloc de fin n'est pas prêt à être exécuté.

Le bloc PROCESS doit être juste appeler une fonction au sein du bloc de fin. Lorsque les objets sont transmis, le bloc PROCESS s'exécutera plusieurs fois, et vous ne voulez pas avoir à appeler à plusieurs reprises le bloc de fin.

Il existe quelques méthodes sournois pour résoudre le problème, mais l'approche la plus simple est souvent la meilleure : lorsque vous avez besoin d'un type d'activité de nettoyage (comme la fermeture d'une connexion de base de données), oubliez sur l'utilisation de blocs BEGIN et END complètement. Disposer le bloc PROCESS ne supposer que destination pour exécuter une seule fois et simplement placer tous vos paramètres et nettoyage à cet endroit.

Il peut être un peu gaspillage — il peut également ouvrir et fermer la connexion de base de données à plusieurs reprises, par exemple — mais il est efficace. Il élimine également la nécessité de devoir perambulations bizarre et difficile à suivre dans votre code.

Ces fonctions pour gérer le pipeline et non pipeline scénarios de programmation peut être difficile. Dans certaines colonnes à venir, je vous ferai part de quelques-unes des méthodes qu'autres personnes ont résolu ce problème, afin de disposer de différentes options à utiliser dans votre propre environnement.

Denny Cherry

Don Jones est un destinataire de la récompense MVP de Microsoft et auteur d'au "en savoir plus Windows PowerShell dans un mois de déjeuner » (Manning Publications Co., 2010), un livre conçu pour aider tous les administrateurs entrent en vigueur avec Windows PowerShell. Jones propose également une formation Windows PowerShell public et sur place. Vous pouvez le contacter sur son site Web à ConcentratedTech.com.

Contenu associé