demande de rappel immédiat

"PowerShell.exe" ne sait pas démarrer sans afficher une fenêtre

Posted by Jean-Paul Blanc Friday, January 28, 2011 9:28:00 PM
Rate this Content 0 Votes

 

 slxPowerShell

En fait j'ai trouvé deux réponses sur la toile.

La première solution consiste à invoquer powershell à travers un script .VBS

C'est ce qu'illustre le bout de code ci-dessous :

 1: Set Args = Wscript.Arguments
 2: 'MsgBox "Chemin LDAP: " & Args(0)
 3: 'MsgBox "Classe: " & Args(1)
 4:  
 5: Set objShell = CreateObject("Wscript.Shell")
 6: objShell.Run "c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -nologo -Noninteractive -file c:\SlxRH\RhModif.ps1 " & chr(34) & Args(0) & chr(34) , 0

Pour information j'ai écrit ce script pour l'inscrire dans l'attribut "adminContextMenu" du "Display Specifier" de la classe "user" de l'arbre (contexte de nommage) de configuration de l'annuaire Active Directory. Cet attribut permet d'ajouter un menu contextuel supplémentaire sur les objets de type utilisateur de la MMC utilisateur et ordinateurs Active directory. Ce script est invoqué lors d'un clic sur le menu contextuel.

Cette solution est très répendue sur le NET.Dans la pratique tout réside dans le ",0" à la fin de la dernière ligne.

Bien que cela fonctionne, je ne trouve pas élégant de passer par WSH (Windows Script Host) pour démarrer un script Powershell, ce n'est pas homogène.


La seconde solution consiste à embarquer un espace d'exécution powershell dans un programme .NET écrit en C#.

Je suis parti de l'exemple simple ci-dessous trouvé sur un autre blog internet.

using System;
using System.Management.Automation.Runspaces;
using System.Windows.Forms;

namespace PowershellRunner
{
    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            try
            {
                if (args == null || args.Length != 1)
                    throw new ApplicationException("Empty argument list");
                Runspace runspace = RunspaceFactory.CreateRunspace();
                runspace.Open();
                Pipeline pipeline = runspace.CreatePipeline();
                pipeline.Commands.AddScript(args[0]);
                pipeline.Invoke();
            }
            catch(Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }
    }
}

Pour compiler ce programme il faut :

  • Télécharger et installer le SDK de PowerShell V2.
  • Dans Visual Studio 2010, partir d'un projet de type "application Windows" (pas une application Console)
  • Ajouter une référence sur l'assembly "System.Management.Automation"(fichier "C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0\System.Management.Automation.dll")

Cette version de base permet de comprendre le principe mais ne gère pas les paramètres de la ligne de commande. Pour ma part j'ai eu besoin d'un programme capable de prendre en charge a la fois :

  • Le démarrage de scripts PowerShell (fichiers .PS1).
  • L'interprétation de commandes PowerShell

Vous trouverez dans les ressources PowerShell le fichier "slxPShell.cs" qui est une version retouchée de ce programme :

La syntaxe d'utilisation est la suivante :

Pour le lancement d'un script avec passage d'arguments :

slxPShell "Script.ps1" "Arg1" "Arg2" ... "Argn"
SlxPShell.exe ".\Aff le loup.ps1" coucou "12 13"

Pour l'interprétation de commandes PowerShell :

slxPShell "{... commandes ...}" "Arg1" "Arg2" ... "Argn"

 

Remarque importante : dans le cadre de l'interprétation de commandes, il faut faire extrêmement attention au contexte d'appel et notamment à l'interprétation des caractères particuliers de l'invite dans laquelle la commande est passée.

Exemple d'interprétation de commandes par slxPShell depuis Powershell :

SlxPShell.exe "{`$a=500;[console]::Beep(`$a,`$args[0]);}" 1000
SlxPShell.exe "{`$a='Une Chaine';Set-Content `$args[0] `$a;}" .\f.txt

 

Exemple d'interprétation de commandes par slxPShell depuis Cmd. C'est le cas de figure dans lequel je me retrouve chaque fois que c'est le système d'exploitation qui invoque slxPShell (ouverture de session, ajout de menus contextuels).

SlxPShell.exe "{$a=500;[console]::Beep($a,$args[0]);}" 1000
SlxPShell.exe "{$a=\"Une Chaine\";Set-Content $args[0] $a;}" .\f.txt

Astuce : Le simple caractère ':' placé en premier caractère du premier paramètre permet de visualiser la commande PowerShell envoyée dans le "pipeline".

Téléchargement :

 

Comments are closed on this post.