preloader
30 September 2010 / #.net

Powershell et VB.NET

Powershell est un très bon langage de programmation, mais reste un langage interprété alors que VB .NET est quand à lui un langage compilé.

Je ne m’attarderais pas ici sur la diférence entre les 2, cependant dans certains cas, une application compilée est plus adapté qu’un script interprété.

En fait, on peut finalement avoir le beurre et l’argent du beurre puisqu’il est possible depuis un programme VB .NET de créer un runspace et d’appeler des commandes Powershell dans un pipeline se basant sur ce runspace.

Il est facile alors de pouvoir invoquer des commandes Powershell directement dans un programme VB .NET !

Edit : Je tenais à remercier Akakaka (il se reconnaîtra ^^) pour ses idées !

Tout d’abord, il convient d’importer certaines assemblies dans le programme VB .NET :

Imports System.Management.Automation
Imports System.Management.Automation.Runspaces
Imports System.Collections.ObjectModel

Ensuite, on peut passer par une classe qui sera dédié à l’exécution de commande Powershell dans le programme :

'Classe gestion PowerShell
Public Class PwShell
    Dim runSpace As Runspace
    Dim pipeLine As Pipeline

    Sub New()
        ' runspace
        runSpace = RunspaceFactory.CreateRunspace()
        ' open it
        runSpace.Open()
        exec("Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin")
    End Sub

    Function exec(ByVal cmd As String) As Collection(Of PSObject)
        pipeLine = runSpace.CreatePipeline()
        pipeLine.Commands.AddScript(cmd)

        Dim outobjects = pipeLine.Invoke

        Dim outerror = pipeLine.Error.ReadToEnd
        If outerror.Count > 0 Then
            Dim allerrors As String = ""
            For Each elem As PSObject In outerror
                Dim erreur = DirectCast(elem.BaseObject, Management.Automation.ErrorRecord)
                allerrors &= erreur.Exception.Message

            Next
            Throw New Exception(allerrors)
        End If

        Return outobjects
    End Function

    Sub close()
        runSpace.Close()
    End Sub
End Class

Lorsque l’on regarde le constructeur de la classe Sub New() on voit que l’on charge automatiquement le pipeline avec la commande Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin qui permet automatiquement de charger le module de gestion Exchange 2007 (rendant par la suite disponible les cmdlets propre à Exchange 2007).

Edit : ajoue de la gestion des erreurs (en se basant sur le projet : http://www.codeproject.com/KB/threads/AsyncPowerShell.aspx

Une fois la classe créée, il suffit de l’instancier par le code suivant :

Dim ps As New PwShell

Ensuite, on peut profiter de la méthode exec qui permet d’exécuter des commandes Powershell à la volée :

Dim results = ps.exec("Get-PublicFolder -Identity '\' -getchildren -ResultSize Unlimited")

> Frederic MARTIN