IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Execution d'un script PowerShell depuis une appli C#


Sujet :

C#

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 10
    Par défaut Execution d'un script PowerShell depuis une appli C#
    Bonjour,

    Je cherche à executer un script Powershell depuis mon application. Si je le fais en utilisant la classe PowerShell, en faisant un AddScript pour ajouter mon script puis un Invoke, tout se déroule correctement. Cependant cela ouvre une fenetre powershell en arrière plan.

    J'ai donc trouvé sur internet une solution qui consiste à utiliser la classe ProcessStartInfo :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = "powershell.exe",        // Utiliser PowerShell pour exécuter le script
        Arguments = arguments,             // Passer les arguments de la commande
        CreateNoWindow = true,             // Ne pas créer de fenêtre PowerShell
        UseShellExecute = false,           // Ne pas utiliser l'interface utilisateur du shell
        RedirectStandardOutput = true,     // Rediriger la sortie du script vers l'application
        RedirectStandardError = true      // Rediriger les erreurs aussi
    };
    Avec dans arguments mon script. Mais quand je fais ainsi, j'ai une erreur sur les lignes ou apparait la variable $env. Par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FilePath = $env:SystemRoot\Temp\MAS_$rand.cmd;
    L'erreur est la suivante : La référence à la variable n'est pas valide. $ n'est pas suivi d'un caractère de nom de variable valide. Envisagez d'utiliser ${} pour délimiter le nom.

    Est-ce qu'il y a quelque chose de spécial à faire dans le cas ou on ne passe pas par la classe PowerShell ?

    Merci d'avance pour votre aide.

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 537
    Par défaut
    regarde l'aide de la commande powershell, ça devrait te donner une piste
    Si ton script est un fichier, il faut l'argument -File, sinon -Command {....}

    powershell /?

    PowerShell[.exe] [-PSConsoleFile <fichier> | -Version <version>]
    [-NoLogo] [-NoExit] [-Sta][-Mta] [-NoProfile] [-NonInteractive]
    [-InputFormat {Text | XML}] [-OutputFormat {Text | XML}]
    [-WindowStyle <style>] [-EncodedCommand <Commande codée en base 64>]
    [-ConfigurationName <chaîne>]
    [-File <chemin d’accès du fichier> <arguments>] [-ExecutionPolicy <Stratégie d’exécution>]
    [-Command { - | <bloc de script> [-args <tableau d’arguments>]
    | <chaîne> [<Paramètres de la commande>] } ]

    PowerShell[.exe] -Help | -? | /?

    -PSConsoleFile
    Charge le fichier de console Windows PowerShell spécifié. Pour créer un
    fichier de console, utilisez Export-Console dans Windows PowerShell.

    -Version
    Démarre la version spécifiée de Windows PowerShell.
    Entrez un numéro de version avec le paramètre, tel que « -version 2.0 ».

    -NoLogo
    Masque la bannière de copyright au démarrage.

    -NoExit
    Ne se ferme pas après l’exécution des commandes de démarrage.

    -Sta
    Démarre l’interpréteur de commandes à l’aide d’un cloisonnement monothread.
    Le cloisonnement monothread (STA) est utilisé par défaut.

    -Mta
    Démarrer l’interpréteur de commandes à l’aide d’un cloisonnement multithread.

    -NoProfile
    Ne charge pas le profil Windows PowerShell.

    -NonInteractive
    N’affiche pas d’invite interactive pour l’utilisateur.

    -InputFormat
    Décrit le format des données envoyées à Windows PowerShell. Les valeurs
    valides sont « Text » (chaînes de texte) ou « XML » (format CLIXML sérialisé).

    -OutputFormat
    Détermine la méthode de mise en forme de la sortie de Windows PowerShell.
    Les valeurs valides sont « Text » (chaînes de texte) ou « XML » (format CLIXML sérialisé).

    -WindowStyle
    Définit le style de fenêtre sur Normal, Minimized, Maximized ou Hidden.

    -EncodedCommand
    Accepte une version de chaîne codée en base 64 d’une commande. Utilisez
    ce paramètre pour envoyer des commandes à Windows PowerShell nécessitant
    des guillemets complexes ou des accolades.

    -ConfigurationName
    Spécifie un point de terminaison de configuration dans lequel Windows PowerShell est exécuté.
    Il peut s’agir de tout point de terminaison enregistré sur la machine locale, notamment les
    points de terminaison à distance par défaut Windows PowerShell, ou un point de terminaison personnalisé
    doté de capacités spécifiques au rôle utilisateur.

    -File
    Exécute le script spécifié dans l’étendue locale (avec « dot-sourcing »), de sorte que les
    fonctions et variables créées par le script soient disponibles dans la
    session active. Entrez le chemin d’accès au fichier de script et les paramètres éventuels.
    Le fichier doit être le dernier paramètre de la commande, car tous les caractères
    entrés après le nom de paramètre File sont interprétés
    comme étant le chemin d’accès au fichier de script, suivi des paramètres du script.

    -ExecutionPolicy
    Définit la stratégie d’exécution par défaut de la session active et l’enregistre
    dans la variable d’environnement $envSExecutionPolicyPreference.
    Ce paramètre ne modifie pas la stratégie d’exécution Windows PowerShell
    définie dans le Registre.

    -Command
    Exécute les commandes spécifiées (et les paramètres éventuels) comme si elles étaient
    entrées dans l’invite de commandes Windows PowerShell, puis se ferme, sauf si
    NoExit est spécifié. La valeur de la commande peut être « - », une chaîne ou un
    bloc de script.

    Si la valeur de la commande est « - », le texte de la commande est lu dans
    l’entrée standard.

    Si la valeur de la commande est un bloc de script, celui-ci doit être placé
    entre accolades ({}). Vous pouvez spécifier un bloc de script uniquement
    lorsque vous exécutez PowerShell.exe dans Windows PowerShell. Les résultats du bloc de script sont renvoyés à l’interpréteur de commandes
    parent sous forme d’objets XML désérialisés et non pas sous forme d’objets actifs.

    Si la valeur de la commande est une chaîne, la commande doit être le dernier
    paramètre de la commande, car les caractères entrés après la commande sont
    interprétés comme arguments de commande.

    Pour écrire une chaîne qui exécute une commande Windows PowerShell,
    utilisez le format :
    "& {<commande>}"
    où les guillemets indiquent une chaîne et l’opérateur d’appel (&)
    entraîne l’exécution de la commande.

    -Help, -?, /?
    Affiche ce message. Si vous entrez une commande PowerShell.exe dans Windows
    PowerShell, préfixez les paramètres de la commande avec un tiret (-) et
    non pas avec une barre oblique (/). Vous pouvez utiliser un tiret ou une barre oblique dans Cmd.exe.

    EXAMPLES
    PowerShell -PSConsoleFile SqlSnapIn.Psc1
    PowerShell -version 2.0 -NoLogo -InputFormat text -OutputFormat XML
    PowerShell -ConfigurationName AdminRoles
    PowerShell -Command {Get-EventLog -LogName security}
    PowerShell -Command "& {Get-EventLog -LogName security}"

    # Pour utiliser le paramètre -EncodedCommand :
    $command = 'dir "c:\program files" '
    $bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
    $encodedCommand = [Convert]::ToBase64String($bytes)
    powershell.exe -encodedCommand $encodedCommand

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 10
    Par défaut
    Merci pour votre réponse.
    J'ai creusé un peu, et voici ce qui se passe. J'utilise un script très simple pour tester:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    string scriptContent = "$FilePath = \"$env:SystemRoot\\Temp\\MAS_123.cmd\";" +
    "echo $FilePath";
    Et ensuite je fais ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    string arguments = $"-NoProfile -ExecutionPolicy Bypass -Command \"{scriptContent}\"";
     
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = "powershell.exe",
        Arguments = arguments,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardError = true
    };
     
    // Démarrer le processus PowerShell
    using (Process process = Process.Start(startInfo))
    {
        // Lire la sortie et les erreurs, le cas échéant
        string output = await ReadOutputAsync(process.StandardOutput);
        string errors = await ReadOutputAsync(process.StandardError);
    }
    Et j'ai dans errors le message suivant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Au caractŠre Ligne:1 : 28
    + $FilePath = $env:SystemRoot\Temp\MAS_123.cmd;echo $FilePath
    +                            ~~~~~~~~~~~~~~~~~
    Jeton inattendu ®ÿ\Temp\MAS_123.cmdÿ¯ dans l'expression ou l'instruction.
        + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
        + FullyQualifiedErrorId : UnexpectedToken
    Par contre si j'enregistre les 2 lignes du script dans un fichier, et qu'ensuite je définis arguments de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    string arguments = $"-NoProfile -ExecutionPolicy Bypass -File \"E:\\script.ps1\"";
    Là ça fonctionne.

    Donc je pense que le problème viens du fait que je transmets le script en paramètre, je pense que le texte est mal interprété. Est-ce que quelqu'un a une idée pour corriger ce problème ?

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Septembre 2010
    Messages
    1 537
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Septembre 2010
    Messages : 1 537
    Par défaut
    Probablement à cause de ça:
    Si la valeur de la commande est un bloc de script, celui-ci doit être placé
    entre accolades ({}).
    donc ton script devrait être entré ainsi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    string scriptContent = "$FilePath = \"$env:SystemRoot\\Temp\\MAS_123.cmd\";" +
    "echo $FilePath";
     
    string arguments = "-NoProfile -ExecutionPolicy Bypass -Command {"+$"{scriptContent}"+"}";
     
    ProcessStartInfo startInfo = new ProcessStartInfo
    {
        FileName = "powershell.exe",
        Arguments = arguments,
        UseShellExecute = false,
        RedirectStandardOutput = true,
        RedirectStandardError = true
    };
     
    // Démarrer le processus PowerShell
    using (Process process = Process.Start(startInfo))
    {
        // Lire la sortie et les erreurs, le cas échéant
        string output = await ReadOutputAsync(process.StandardOutput);
        string errors = await ReadOutputAsync(process.StandardError);
    }
    [/code]

Discussions similaires

  1. [MySQL] Execution d'un script bash depuis une page PHP qui se trouve sur un autre serveur
    Par Whisper40 dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 08/07/2018, 15h20
  2. Réponses: 2
    Dernier message: 17/10/2016, 14h08
  3. Réponses: 1
    Dernier message: 15/02/2009, 07h45
  4. Exécuter un script SQL depuis une procédure PL/SQL
    Par rvfranck dans le forum PL/SQL
    Réponses: 8
    Dernier message: 19/04/2008, 01h11
  5. Réponses: 5
    Dernier message: 15/07/2004, 23h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo