Exécuter le script PowerShell à partir de C # avec des arguments de ligne de commande

Je dois exécuter un script PowerShell depuis C #. Le script nécessite des arguments en ligne de commande.

C’est ce que j’ai fait jusqu’ici:

RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); Pipeline pipeline = runspace.CreatePipeline(); pipeline.Commands.Add(scriptFile); // Execute PowerShell script results = pipeline.Invoke(); 

scriptFile contient quelque chose comme “C: \ Program Files \ MyProgram \ Whatever.ps1”.

Le script utilise un argument de ligne de commande tel que “-key Value”, tandis que Value peut être quelque chose comme un chemin pouvant également contenir des espaces.

Je ne comprends pas ça. Est-ce que quelqu’un sait comment transmettre des arguments de ligne de commande à un script PowerShell depuis C # et s’assurer que les espaces ne posent aucun problème?

Essayez de créer un script en tant que commande distincte:

 Command myCommand = new Command(scriptfile); 

alors vous pouvez append des parameters avec

 CommandParameter testParam = new CommandParameter("key","value"); myCommand.Parameters.Add(testParam); 

et enfin

 pipeline.Commands.Add(myCommand); 

Voici le code complet édité:

 RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); Pipeline pipeline = runspace.CreatePipeline(); //Here's how you add a new script with arguments Command myCommand = new Command(scriptfile); CommandParameter testParam = new CommandParameter("key","value"); myCommand.Parameters.Add(testParam); pipeline.Commands.Add(myCommand); // Execute PowerShell script results = pipeline.Invoke(); 

J’ai une autre solution. Je veux juste tester si l’exécution d’un script PowerShell réussit, car peut-être quelqu’un pourrait changer la politique. Comme argument, je spécifie simplement le chemin du script à exécuter.

 ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = @"powershell.exe"; startInfo.Arguments = @"& 'c:\Scripts\test.ps1'"; startInfo.RedirectStandardOutput = true; startInfo.RedirectStandardError = true; startInfo.UseShellExecute = false; startInfo.CreateNoWindow = true; Process process = new Process(); process.StartInfo = startInfo; process.Start(); ssortingng output = process.StandardOutput.ReadToEnd(); Assert.IsTrue(output.Contains("SsortingngToBeVerifiedInAUnitTest")); ssortingng errors = process.StandardError.ReadToEnd(); Assert.IsTrue(ssortingng.IsNullOrEmpty(errors)); 

Avec le contenu du script étant:

 $someVariable = "SsortingngToBeVerifiedInAUnitTest" $someVariable 

Toute chance d’obtenir plus de clarté sur les parameters de transmission de la méthode Commands.AddScript?

C: \ Foo1.PS1 Bonjour World Faim C: \ Foo2.PS1 Bonjour tout le monde

scriptFile = “C: \ Foo1.PS1”

parameters = “parm1 parm2 parm3” … longueur variable des parameters

Resolved this … en passant null en tant que nom et le paramètre en tant que valeur dans une collection de CommandParameters

Voici ma fonction:

 private static void RunPowershellScript(ssortingng scriptFile, ssortingng scriptParameters) { RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create(); Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration); runspace.Open(); RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace); Pipeline pipeline = runspace.CreatePipeline(); Command scriptCommand = new Command(scriptFile); Collection commandParameters = new Collection(); foreach (ssortingng scriptParameter in scriptParameters.Split(' ')) { CommandParameter commandParm = new CommandParameter(null, scriptParameter); commandParameters.Add(commandParm); scriptCommand.Parameters.Add(commandParm); } pipeline.Commands.Add(scriptCommand); Collection psObjects; psObjects = pipeline.Invoke(); } 

Vous pouvez également utiliser le pipeline avec la méthode AddScript:

 ssortingng cmdArg = ".\script.ps1 -foo bar" Collection psresults; using (Pipeline pipeline = _runspace.CreatePipeline()) { pipeline.Commands.AddScript(cmdArg); pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output); psresults = pipeline.Invoke(); } return psresults; 

Il faudra une chaîne, et quels que soient les parameters que vous lui transmettez.

Voici un moyen d’append des parameters au script si vous avez utilisé

 pipeline.Commands.AddScript(Script); 

Cela consiste à utiliser HashMap comme paramètre, la clé étant le nom de la variable dans le script et la valeur étant la valeur de la variable.

 pipeline.Commands.AddScript(script)); FillVariables(pipeline, scriptParameter); Collection results = pipeline.Invoke(); 

Et la méthode de la variable de remplissage est la suivante:

 private static void FillVariables(Pipeline pipeline, Hashtable scriptParameters) { // Add additional variables to PowerShell if (scriptParameters != null) { foreach (DictionaryEntry entry in scriptParameters) { CommandParameter Param = new CommandParameter(entry.Key as Ssortingng, entry.Value); pipeline.Commands[0].Parameters.Add(Param); } } } 

De cette façon, vous pouvez facilement append plusieurs parameters à un script. J’ai aussi remarqué que si vous voulez obtenir une valeur d’une variable dans votre script comme ceci:

 Object resultcollection = runspace.SessionStateProxy.GetVariable("results"); 

// les résultats étant le nom du v

Vous devrez le faire comme je vous l’ai montré car, pour une raison quelconque, si vous le faites comme le suggère Kosi2801, la liste des variables de script ne contient pas vos propres variables.

Le mien est un peu plus petit et plus simple:

 ///  /// Runs a PowerShell script taking it's path and parameters. ///  /// The full file path for the .ps1 file. /// The parameters for the script, can be null. /// The output from the PowerShell execution. public static ICollection RunScript(ssortingng scriptFullPath, ICollection parameters = null) { var runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); var pipeline = runspace.CreatePipeline(); var cmd = new Command(scriptFullPath); if (parameters != null) { foreach (var p in parameters) { cmd.Parameters.Add(p); } } pipeline.Commands.Add(cmd); var results = pipeline.Invoke(); pipeline.Dispose(); runspace.Dispose(); return results; } 

Pour moi, le moyen le plus flexible d’exécuter un script PowerShell à partir de C # était d’utiliser PowerShell.Create (). AddScript ()

L’extrait de code est

 ssortingng scriptDirectory = Path.GetDirectoryName( ConfigurationManager.AppSettings["PathToTechOpsTooling"]); var script = "Set-Location " + scriptDirectory + Environment.NewLine + "Import-Module .\\script.psd1" + Environment.NewLine + "$data = Import-Csv -Path " + tempCsvFile + " -Encoding UTF8" + Environment.NewLine + "New-Registration -server " + dbServer + " -DBName " + dbName + " -Username \"" + user.Username + "\" + -Users $userData"; _powershell = PowerShell.Create().AddScript(script); _powershell.Invoke(); foreach (var errorRecord in _powershell.Streams.Error) Console.WriteLine(errorRecord); 

Vous pouvez vérifier s’il y a une erreur en cochant Streams.Error. C’était très pratique de vérifier la collection. User est le type d’object renvoyé par le script PowerShell.