Parlons un peu de Powershell

Je l’avoue c’est volontairement un peu racoleur de mettre ce genre de termes dans un article traitant de PowerShell. Le but n’est pas ici de vous induire en erreur mais bien de voir comment pousser un peu PowerShell pour voir comment il se comporte quand nous l’utilisons d’une manière un peu moins conventionnelle.

Je vais essayer dans les semaines à venir de vous parler un peu plus PowerShell car je pense qu’aujourd’hui encore c’est un formidable outil mal connu par certains et mal appréhendé par beaucoup.

Cher développeur .Net, dit toi bien que si Google et Visual Studio sont tes amis, PowerShell se doit de l’être lui aussi et d’être dans le trio de tête. Revenons rapidement sur un certain nombre de faits ou idées reçues:

Pour moi développeur, Powershell ne sert à rien, c’est un truc d’admins ça

Même si il est vrai qu’un bon admin a plus besoin de maitriser powershell que le bon développeur, il y a beaucoup de tâches répétitives que l’on peu traiter avec powershell, sans compter les petits bouts de programmes console que l’on développe dans un coin pour traiter un truc alors que cela pourrait être fait avec deux lignes de powershell.

Powershell ça à l’air bien mais pour ce que j’en ai besoin les batch dos me suffisent

Alors oui peut être dans beaucoup de cas mais c’est à mon sens passer à coté de quelque chose. Moi même pendant longtemps j’ai eut la flemme de m’y mettre en me disant que les scripts dos me suffisaient. Résultat, je continuai à faire certaines tâches à la main car trop compliquées à écrire. Je faisais des bouts de console jetable pour des choses qui pouvaient être scriptées et j’en passe.

La syntaxe est un peu trop bizarre, je comprend rien.

Un peu déroutant au début peut être mais si on part du postulat que powershell est basé sur .net/c#, que c’est un environnement orienté script et basé des commandes qui peuvent être chainées (I love Pipe ;-) ), cela devient assez évident au final. De plus powershell en plus d’être assez intuitif pour tout développeur c# est très efficace en auto-documentation.

 

Nous allons donc revenir sur un certains nombre de fonctionnements qui ne sont pas forcément des plus courants en powershell mais qui bien utilisés peuvent être des plus pratiques.

 

Revenons à notre titre

J’aimerai quelque chose qui ressemble à mes delegates

Commençons tout d’abord par créer deux fonctions d’exemple très simple:

2010-10-10_0041

qui produira bien sur le résultat suivant:

2010-10-10_0055

Le principe du délegate est de pouvoir déférer une action. On utilise une action qui répond à un certain modèle mais qui ne sera réellement définie que plus tard. Powershell, un peu à la manière de javascript accepte indifféremment un paramètre de type valeur/référence qu’un paramètre de type fonction. Le plus important à connaitre est finalement le ‘&’ qui indique à l’interpréteur que le token doit être exécuté.  

Nous avons ici des jolies fonctions qui peuvent faire coucou, très bien. Maintenant imaginons que je veuille passer une liste de noms à mes fonctions pour faire coucou à tout le monde. Soit je dois réécrire une fonction qui traite la liste en argument, soit j’encapsule le tout, par exemple:

2010-10-10_0101

Je vous laisse vous faire une idée du résultat. Le problème est qu’il faut écrire une fonction qui prend en paramètre une liste pour chacune de mes fonctions sources alors qu’elles ont la même signature. Réécrivons donc cette fonction en mode delegate:

2010-10-10_0104

C’est d’un coup beaucoup plus pratique et lisible. Par contre bien sur, il ne s’agit pas d’un environnement fortement typé et vous ne pourrez pas définir de signatures pour vos délégués. Mais n’oubliez pas que c’est la souplesse plus que la rigidité qui font la force d’un bon environnement de scripting.

 

Les anonymes

Voila encore un terme qui fleure bon le .Net 3.5 et qui parait très éloigné du scripting habituel. Détrompez vous si tel est votre idée. Ces concepts repris à la sauce script peuvent rendre bien des services.

Powershell permet une écriture ressemblant un peu à du json avec une écriture assez similaire au travers de ses hashtables. De plus tout comme le javascript, tout est fait dans le langage pour qu’il soit simple d’écrire ou de consommer de tels conteneurs.

Mais ce type de conteneurs à la json, se rapprochent finalement beaucoup de nos anonymes .net. On pourra dire qu’ils sont de deux types, les objets anonymes qui sont crées à la volée par le compilateur et les méthodes anonymes. J’adore ces conteneurs car ils sont très pratiques et surtout très lisibles.

En powershell, même si ce n’est pas le cas le plus utile, on peut créer une fonction que l’on range dans une variable (cela pourrait correspondre à nos Action<T> ou Func<T,U> de .net), par exemple:

2010-10-10_0122

Ca c’était pour les méthodes, on pourra aussi donc créer quelque chose de ressemblant à un objet anonyme par le biais des hashtables powershell:

2010-10-10_0130

Mais nous pouvons aussi mixer les deux et là nous avons un conteneur vraiment complet et pratique tel que l’on en utilise aujourd’hui dans du javascript avancé:

2010-10-10_0137

Encore une fois c’est le & qui fait tout, notre fonction anonyme ne serait rien si on ne savait pas comment l’invoquer!

Notes au passage pour ceux qui découvrent un peu powershell:

  • le string.format(“machaine”,param1,param2,param3”) de .net est traduit par:  “machaine” –f param1,param2,param3
  • dans cette même chaine, toute variable sera remplacée par sa valeur
  • le caractère d’échappement est le ` (quote inversée). Il sert pour aller à la ligne par exemple `n ou en encore pour échapper une variable: “$name” mettra la valeur de $name dans la chaine alors que “`$name” écrira $name dans la chaine.
  • ce même caractère d’échappement peut servir pour faire des ‘continuer à la ligne suivante’

Juste pour finir sur les anonymes, l’intérêt est aussi de bien comprendre qu’en powershell on peut placer un bloc de code un peu où l’on veut, lui attribuer des paramètres simplement en lui rajoutant “param()” au début et surtout l’utiliser partout. En reprenant notre exemple initial d’execution d’action sur une liste mais en lui passant cette fois-ci une fonction à la volée:

2010-10-10_0149

 

Un exemple: wrapper un try/catch

En reprenant ce que l’on vient de dire, pourquoi ne pas créer un petit wrapper pour écrire simplement des blocs de fonctions encapsulés automatiquement par un try/catch/finally?

2010-10-10_0158

Qui bien sur produira un résultat du genre:

2010-10-10_0159

 

Pour résumer

Nous avons après avoir réintroduit powershell dans son contexte pour le développeur présenté l’intérêt qu’il peut avoir pour ce dernier. Pour se rapprocher au mieux du développeur, nous avons vu une approche de la plateforme powershell une peu différente de celle habituellement utilisée dans le script pour présenter deux concept usuels de .net, les anonymes et les délégués.

Pour ceux qui me demanderaient d’où viennent mes captures de script powershell, ce sera l’objet d’un prochain post, stay tuned Clignement d'œil.

Bon script!