Esegui lo script PowerShell da C # con gli argomenti della riga di comando

Ho bisogno di eseguire uno script PowerShell da C #. Lo script richiede argomenti della riga di comando.

Questo è quello che ho fatto finora:

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 contiene qualcosa come “C: \ Programmi \ MyProgram \ Whatever.ps1”.

Lo script utilizza un argomento della riga di comando come “-key Value” mentre Value può essere qualcosa come un percorso che potrebbe contenere anche spazi.

Non capisco che funzioni. Qualcuno sa come passare gli argomenti della linea di comando a uno script PowerShell da C # e assicurarsi che gli spazi non siano un problema?

Prova a creare scriptfile come comando separato:

 Command myCommand = new Command(scriptfile); 

quindi è ansible aggiungere parametri con

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

e infine

 pipeline.Commands.Add(myCommand); 

Ecco il codice completo e modificato:

 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(); 

Ho un’altra soluzione. Voglio solo verificare se l’esecuzione di uno script di PowerShell ha esito positivo, perché forse qualcuno potrebbe cambiare la politica. Come argomento, ho solo specificato il percorso dello script da eseguire.

 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(); string output = process.StandardOutput.ReadToEnd(); Assert.IsTrue(output.Contains("StringToBeVerifiedInAUnitTest")); string errors = process.StandardError.ReadToEnd(); Assert.IsTrue(string.IsNullOrEmpty(errors)); 

Con il contenuto del copione che è:

 $someVariable = "StringToBeVerifiedInAUnitTest" $someVariable 

Qualche possibilità di ottenere maggiore chiarezza sui parametri che passano al metodo Commands.AddScript?

C: \ Foo1.PS1 Hello World Hunger C: \ Foo2.PS1 Ciao mondo

scriptFile = “C: \ Foo1.PS1”

parameters = “parm1 parm2 parm3” … lunghezza variabile dei parametri

Risolto questo … passando null come il nome e il parametro come valore in una raccolta di CommandParameters

Ecco la mia funzione:

 private static void RunPowershellScript(string scriptFile, string 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 (string 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(); } 

Puoi anche utilizzare la pipeline con il metodo AddScript:

 string 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; 

Prenderà una stringa, e qualunque parametro tu passi.

Ecco un modo per aggiungere parametri allo script se usato

 pipeline.Commands.AddScript(Script); 

Questo è con l’utilizzo di una HashMap come parametri la chiave è il nome della variabile nello script e il valore è il valore della variabile.

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

E il metodo della variabile di riempimento è:

 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 String, entry.Value); pipeline.Commands[0].Parameters.Add(Param); } } } 

in questo modo è ansible aggiungere facilmente più parametri a uno script. Ho anche notato che se vuoi ottenere un valore da una variabile nel tuo script in questo modo:

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

// risulta essere il nome della v

devi farlo nel modo in cui l’ho mostrato, perché per qualche ragione se lo fai come Kosi2801 suggerisce che l’elenco delle variabili di script non si riempia delle tue variabili.

Il mio è un po ‘più piccolo e semplice:

 ///  /// 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(string 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; } 

Per me, il modo più flessibile per eseguire script PowerShell da C # era l’utilizzo di PowerShell.Create (). AddScript ()

Lo snippet del codice è

 string 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); 

Puoi controllare se c’è qualche errore controllando Streams.Error. È stato davvero utile controllare la collezione. L’utente è il tipo di object restituito dallo script PowerShell.