http://michael.carbenay.info

Ajouter une commande à Powershell

01 sept. 2006  –  PowerShell  –  0 Commentaires

Voyons un peu comment faire pour intégrer vos propres commandes dans Powershell, vous allez voir cela n'a rien de sorcier.

1) Création d'une Cmdet

Une Cmdlet (prononcez «Commande-lète») est tout simplement une classe .net représentant une commande sous Powershell comme par exemple Get-ChildItem (la cmdlet standard utilisée - ou plutôt aliasée - pour faire un bon vieux dir).

Comment crée-t-on une Cmdlet donc ? Eh bien, c'est assez simple :

  • créez un nouveau projet «bibilothèque de classe» sous VS2005
  • ajoutez comme référence la dll «System.Management.Automation» (vous la trouverez dans Program Files\Windows PowerShell\v1.0 [update] il vous faudra la récupérer du SDK)
  • créez une nouvelle classe et faites la dériver de System.Management.Automation.Cmdlet
  • ajoutez lui un attribut System.Management.Automation.CmdletAttribute. Ce parametre vous permet de définir le type d'action (paramètre verb) et l'objet (paramètre nounName) sur lequel celui-ci se réalise - pour en savoir plus sur les verbes autorisés, reportez vous à la table suivante : http://blogs.msdn.com/powershell/archive/2006/04/25/583257.aspx)
  • surchargez la méthode BeginProcessing() si vous souhaitez réaliser un traitement avant de traiter les éventuels éléments de la PipeLine
  • et/ou surchargez la méthode EndProcessing() si vous souhaitez réaliser un traitement après de traiter les éventuels éléments de la PipeLine (c'est aussi ici que se font habituellement les traitements de commandes qui ne gèrent pas la Pipeline)
[Cmdlet("Get","MyUser")]
public class GetMyUsersCmdlet : Cmdlet
{
  protected override void< EndProcessing()
  {
    // effectuer le traitement
  }
}

Voila, vous avez déjà une Cmdlet qui peut fonctionner. Bon, évidemment, pour l'instant il n'est pas vraiment question d'une commande intéressante, puisque vous ne pouvez pas lui passer de paramètres ni obtenir de résultat. Cela pourrait être suffisant si vous réalisez une commande destinée à rebooter la machine, mais pour le reste c'est un peu juste.

Voyons donc comment on peut passer des paramètres, mais nous ne nous occuperons pas encore de la Pipeline - cela sera pour un prochain post :

  • pour chacun, ajoutez une propriété en lecture/ecriture (ou un champ) dans votre classe - en faisant bien attention au type que vous utilisez : pas question d'utiliser des types bizarres - mais vous pouvez très bien utiliser une enum.
  • ajoutez sur chacun de ces éléments un System.Management.Automation.ParameterAttribute. Celui-ci vous permettra, après quelques essais, de mieux contrôler la façon dont s'enchainent ou sont obligatoires ou non tous les paramètres.
  • dans votre traitement, utilisez la propriété normalement : elle aura été «remplie» automatiquement par le moteur de PowerShell

public enum TypeUser
{
  Administrateurs,
  Utilisateurs
}

[Cmdlet("Get","MyUser")]
public class GetMyUsersCmdlet : Cmdlet
{
 private TypeUser _typeUser
            = TypeUser.Utilisateurs;
  [Parameter(Mandatory=true)]
  public TypeUser TypeUser
  {
 get { return _typeUser; }
   set { _typeUser = value; }
  }

  protected override void EndProcessing()
  {
   if (_typeUser == TypeUser.Administrateurs)
   {
      // faire le traitement pour les
      // administrateurs
   }
   else
   {
      // faire le traitement pour les
      // utilisateurs normaux
   }
  }
}

Il reste encore une chose à faire pour avoir une Cmdlet digne de ce nom : renvoyer des données. Cela est très simple : il suffit d'appeler la méthode WriteObject pour chacunes des «lignes» de résultats. (Rappelons au passage que les Cmdlets ne renvoie pas forcément du texte, mais peuvent renvoyer n'importe quel type d'objet, dans la limite du raisonnable)

public enum TypeUser
{
  Administrateurs,
  Utilisateurs
}

public class MyUser
{
     ...
}

[Cmdlet("Get","MyUser")]
public class GetMyUsersCmdlet : Cmdlet
{
  private TypeUser _typeUser 
            = TypeUser.Utilisateurs;
  [Parameter(Mandatory=true)]
  public TypeUser TypeUser
  {
   get { return _typeUser; }
   set { _typeUser = value; }
  }

  protected override void EndProcessing()
  {
   if (_typeUser == TypeUser.Administrateurs)
   {
      foreach( ... )
      {
         MyUser usr = new MyUser( ...);
         WriteObject(usr);
      }
   }
   else
   {
      ...

   }
  }
}

Dans le prochain post, nous verrons comment ajouter votre toute nouvelle Cmdlet dans Powershell.

Ajouter un commentaire


(Affichera votre icône Gravatar)

biuquote
  • Commentaire
  • Aperçu immédiat
Loading