Executar script do PowerShell a partir de c # com argumentos de linha de comando

Eu preciso executar um script do PowerShell de dentro do C #. O script precisa de argumentos de linha de comando.

Foi o que eu fiz até agora:

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 contém algo como “C: \ Program Files \ MyProgram \ Whatever.ps1”.

O script usa um argumento de linha de comando como “-key Value”, enquanto Value pode ser algo como um caminho que também pode conter espaços.

Eu não entendo isso para o trabalho. Alguém sabe como passar argumentos de linha de comando para um script do PowerShell de dentro de C # e certifique-se de que os espaços não são problema?

   

    Tente criar o script como um comando separado:

     Command myCommand = new Command(scriptfile); 

    então você pode adicionar parâmetros com

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

    e finalmente

     pipeline.Commands.Add(myCommand); 

    Aqui está o código completo e editado:

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

    Eu tenho outra solução. Eu só quero testar se a execução de um script do PowerShell é bem-sucedida, porque talvez alguém possa alterar a política. Como argumento, eu apenas especifico o caminho do script a ser executado.

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

    Com o conteúdo do script sendo:

     $someVariable = "StringToBeVerifiedInAUnitTest" $someVariable 

    Alguma chance de obter mais clareza sobre os parâmetros de passagem para o método Commands.AddScript?

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

    scriptFile = “C: \ Foo1.PS1”

    parâmetros = “parm1 parm2 parm3” … comprimento variável de params

    Resolvido isso … passando null como o nome e o param como valor em uma coleção de CommandParameters

    Aqui está minha function:

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

    Você também pode simplesmente usar o pipeline com o método 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; 

    Vai levar uma string e quaisquer parâmetros que você passar.

    Aqui está uma maneira de adicionar parâmetros ao script se você usou

     pipeline.Commands.AddScript(Script); 

    Isto é com o uso de um HashMap como parâmetros, sendo a chave o nome da variável no script e o valor é o valor da variável.

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

    E o método da variável de preenchimento é:

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

    Desta forma, você pode facilmente adicionar vários parâmetros a um script. Eu também notei que se você quiser obter um valor de uma variável em seu script da seguinte forma:

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

    // resulta sendo o nome do v

    você terá que fazer do jeito que eu mostrei porque, por algum motivo, se você fizer isso, o Kosi2801 sugere que a lista de variables ​​de script não seja preenchida com suas próprias variables.

    O meu é um pouco mais menor e mais simples:

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

    Para mim, a maneira mais flexível de executar o script do PowerShell a partir do C # era usar o PowerShell.Create (). AddScript ()

    O trecho do código é

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

    Você pode verificar se há algum erro, verificando Streams.Error. Foi muito útil verificar a coleção. Usuário é o tipo de object que o script do PowerShell retorna.