vendredi 23 mai 2008

PowerShell et ASP.NET part 3

Nous voici rendu à la troisième et dernière partie de ce petit tutorial sur PowerShell et ASP.NET

Nous allons voir ici comment piloter un script depuis un formulaire web, et comment déployer ce site sur un serveur IIS convenablement.

Piloter un script

Nous avons vu précédemment comment exécuter du code PowerShell à partir d'une Textbox. Voyons maintenant comment nous pouvons piloter un script en modifiant ces paramètres à la volée.

Ceci est pratique quand vous voulez par exemple faire un portail de provisioning ou d'audit. Plutôt que de proposer à l'utilisateur de taper du code PowerShell, vous pouvez plutôt proposer un formulaire qui va se charger d'exécuter un script avec des paramètres.

Pour illuster ceci, voici un exemple de recherche d'information avec WMI qui peut prendre en argument un nom de machine. j'ai légèrement modifié notre exemple de départ en rajoutant une petite Textbox qui va prendre ce nom de machine :

powerASP4

Voyons maintenant ce qui change côté code. En fait, très peu de chose : Nous allons à présent lire un script incorporé au site web, modifier le contenu et l'exécuter.

Voici le script ajouté au projet :

$strComputer = "*ComputerName*"
get-wmiobject -class "Win32_LogicalDisk" -namespace "root\cimv2" -computername $strComputer where{$_.DriveType –eq 3}out-string


Un script très classique de requête WMI. Comme vous pouvez le voir, j'ai mis le nom de machine en argument. J'ai mis une référence arbitraire de nom "*ComputerName*", qui va me servir pour remplacer cette valeur de variable par le contenu de la TextBox du formulaire.

Voyons le changement opéré dans le code :



        // On the fly script modification before execution


        StreamReader objReader = new StreamReader(Server.MapPath("~/scripts/WmiAsset.ps1"));
        string strContent = objReader.ReadToEnd();
        strContent = strContent.Replace("*ComputerName*", TxtComputerName.Text);
        this.executePowerShellCode(strContent);


Première chose, nous allons lire le fichier contenant le code de notre script. Je l'ai rangé dans un sous-répertoire nommé "scripts", et on utilise simplement à nouveau la librairie system.IO


StreamReader objReader = new StreamReader(Server.MapPath("~/scripts/WmiAsset.ps1"));


Ensuite nous allons mettre l'intégralité du contenu dans une variable, et fermer l'objet StreamReader qui ne nous servira plus :


string strContent = objReader.ReadToEnd();

Ensuite nous utilisons simplement la méthode replace sur cette string, en changeant le code avec le contenu de notre Textbox qui contient le nom de machine.


strContent = strContent.Replace("*ComputerName*", TxtComputerName.Text);

C'est pour ça qu'il est important que le contenu de la variable modifiée soit unique (ici *ComputerName*). Comme vous avez la maitrise du code PowerShell utilisé, ceci est normalement facile à obtenir.

Voilà qui est fait, il ne nous reste plus qu'à exécuter le code comme dans l'exemple précédent.


this.executePowerShellCode(strContent);

Et voilà, rien de bien compliqué si vous avez saisi les précédentes parties. L'intérêt ici est qu'il suffit, en cas de modification de la requête à effectuer, d'aller simplement modifier le fichier .PS1 du répertoire script sur le serveur web, sans avoir à lancer un éditeur C#/ASP.NET.

Vous pouvez bien sûr mettre plusieurs paramètres dans le formulaire. Il reste des choses importantes à implémenter pour une gestion "pro" (prise en compte des erreurs de scripts PowerShell, gestion plus poussé des modes de sorties de script, un contrôle plus adapté que la Textbox pour le suivi des sorties de scripts, etc...) mais vous avez maintenant les bases pour vous lancer, et surtout je l'espère une meilleure compréhension du principe d'interaction envisageable entre le monde web et le scripting PowerShell.

Voyons a présent comment déployer ce portail sur un serveur IIS.

Déploiement du site web

L'intérêt de notre configuration est de pouvoir utiliser un compte de service pour l'exécution des tâches (en l'occurence, l'exécution de nos scripts). Cela simplifie la définition des droits et le modèle de délégation, car il n'est plus nécessaire de donner des droits administratifs spécifiques à chaque utilisateur.

Nous avons néanmoins le besoin de connaitre l'identité de l'utilisateur à l'origine de l'exécution d'une commande afin de se conformer au pré-requis de sécurité sur la production.

La stratégie pour votre déploiement côté IIS doit donc être la suivante :

Tout d'abord filtrer l'accès au site. Pour cela, il suffit simplement de définir des droits appropriés côté NTFS sur l'emplacement de publication. L'idéal étant de définir un groupe d'accès auquel vous donner les droits de lecture sur le site (côte NTFS), et de rajouter les membres adéquats.

Côté IIS, il suffit de faire une publication classique, en désactivant l'accès "anonymous" au site web, et de sélectionner "Integrated Windows Authentification"

powerASP5

Ensuite, il faut définir un application pool pour déléguer l'exécution du code à un compte de service. Pour cela, créer un nouvel application pool, ouvrez ses propriétés et définissez l'Identité dans l'onget approprié.

powerASP6

Il ne vous reste plus qu'à définir cet application pool dans votre site web :

PowerASP7

Modifiez enfin votre web.config pour prendre en charge l'impersonalisation.

Vous devez avoir la ligne "authentication mode", rajoutez en dessous le code suivant :


        <authentication mode="Windows"/>
    <identity impersonate="true"/>
Et voilà, votre site est maintenant prêt pour l'impersonalisation, et l'accès est filtré par les droits NTFS.

En espérant que ce petit tutorial vous aura donner quelques idées, je reviendrai très prochainement sur un concept un peu plus poussé de portail web combinant ASP.NET 3.5, PowerShell, AJAX et Silverlight !

Voici la source de l'exemple de cette partie PowerShellASP2

7 commentaires:

blackboba a dit…

Bonjour,
Je débute dans ce domaine.(projet visual studio et asp.net)
Mais c'est exactement ce que je cherche à faire.
J'ai de bonnes notions Posh pour mes taches courantes et voualait faire un petit portail asp comme par exemple entrez un login est renvoyé les resultat de l'utilsateur sur une page web.
Et ainsi mettre en place des functions posh que j'ai créé et qui seront plus faciles à utiliser pour mes collegues.
Serait il possible d'avoir le code de cette partie 3 afin que je m'en inspire en effet le lien ne fonctionne plus merci d'avance

blackboba a dit…
Ce commentaire a été supprimé par l'auteur.
Antoine Habert a dit…

Bonjour,

Vous pouvez utiliser le code de cet article:

http://devinfra.blogspot.fr/2011/02/execution-de-powershell-20-dans-un-site.html

blackboba a dit…

merci pour cette réponse rapide, j'ai bien évidement déjà essayer cet article ...

mais cela ne me convient pas tout a fait car il faut entrer le code posh dans la txt-box alors qu'ici c’était parfait un paramètre en texte box que l'on parse au script posh qui s’exécute directement pas le bouton.

Antoine Habert a dit…

C'est effectivement le cas, mais la solution est relativement simple: plutôt que d'envoyer le code de la textbox en tant que script, vous n'avez qu'à mettre votre script dans une variable, et remplacer le code voulu par le contenu de la textbox.

si vous mettez par exemple %MAVARIABLE% dans votre script, vous pouvez remplacer ce %MAVARIABLE% par le contenu de la textbox.

blackboba a dit…

cela semble simple a vous lire et à lire la part1 pour la part2 c'est deja un peu plus dur à suivre.

Mais la je ne trouve pas
dommage c'etait vraiment ce que je cherchais a faire
avec des get-mailbox %mavarialbleUser% | get-mailboxstatistiques | fl

mais la je ne m'en sort pas.

Antoine Habert a dit…

string monscript = "get-mailbox %mavarialbleUser% | get-mailboxstatistiques | fl"

monscript.Replace("%mavarialbeUser%",NomTextBox.Text)

(mettre le nom de votre textbox a la place de NomTextBox)

puis executer "monscript"

this.executePowerShellCode(monscript)

ça va pas chercher plus loin que ça pourtant.