Выполнение сценария PowerShell из C# с аргументами командной строки
Мне нужно выполнить сценарий PowerShell из C#. Сценарий нуждается в аргументах командной строки.
Это то, что я сделал до сих пор:
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 содержит что-то вроде "C:Program файлыMyProgramWhatever. ps1".
скрипт использует аргумент командной строки, такой как" - key Value", тогда как Value может быть чем-то вроде пути, который также может содержать пробелы.
Я не могу заставить это работать. Кто-нибудь знает, как передать командную строку аргументы в скрипт PowerShell в C#, и убедитесь, что пробелы не являются проблемой?
7 ответов:
попробуйте создать scriptfile в виде отдельной команды:
Command myCommand = new Command(scriptfile);
затем вы можете добавить параметры с
CommandParameter testParam = new CommandParameter("key","value"); myCommand.Parameters.Add(testParam);
и наконец
pipeline.Commands.Add(myCommand);
вот полный, отредактированный код:
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();
у меня есть другое решение. Я просто хочу проверить, успешно ли выполняется сценарий PowerShell, потому что, возможно, кто-то может изменить политику. В качестве аргумента я просто указываю путь скрипта, который будет выполняться.
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));
с содержимым скрипта:
$someVariable = "StringToBeVerifiedInAUnitTest" $someVariable
любой шанс, что я мог бы получить больше ясности в передаче параметров командам.Метод AddScript?
C:\Foo1.PS1 Привет Мировой Голод C:\Foo2.PS1 Привет, Мир
scriptFile = "C:\Foo1.PS1"
parameters = "parm1 parm2 parm3"... переменной длины параметры
разрешил эту проблему ... передача null в качестве имени и param в качестве значения в коллекцию CommandParameters
вот моя функция:
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<CommandParameter> commandParameters = new Collection<CommandParameter>(); foreach (string scriptParameter in scriptParameters.Split(' ')) { CommandParameter commandParm = new CommandParameter(null, scriptParameter); commandParameters.Add(commandParm); scriptCommand.Parameters.Add(commandParm); } pipeline.Commands.Add(scriptCommand); Collection<PSObject> psObjects; psObjects = pipeline.Invoke(); }
вы также можете просто использовать конвейер с помощью метода AddScript:
string cmdArg = ".\script.ps1 -foo bar" Collection<PSObject> psresults; using (Pipeline pipeline = _runspace.CreatePipeline()) { pipeline.Commands.AddScript(cmdArg); pipeline.Commands[0].MergeMyResults(PipelineResultTypes.Error, PipelineResultTypes.Output); psresults = pipeline.Invoke(); } return psresults;
он будет принимать строку и любые параметры, которые вы передаете его.
вот способ, чтобы добавить параметры в скрипт, если вы использовали
pipeline.Commands.AddScript(Script);
это с использованием HashMap в качестве paramaters ключ, являющийся именем переменной в скрипте, а значение-значением переменной.
pipeline.Commands.AddScript(script)); FillVariables(pipeline, scriptParameter); Collection<PSObject> results = pipeline.Invoke();
и метод переменной заполнения:
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); } } }
таким образом, вы можете легко добавить несколько параметров в скрипт. Я также заметил, что если вы хотите получить значение из переменной в скрипт, как вы Итак:
Object resultcollection = runspace.SessionStateProxy.GetVariable("results");
/ / результаты - это имя v
вы должны сделать это так, как я показал, потому что по какой-то причине, если вы делаете это так Kosi2801 предполагает, что список переменных скрипта не заполняется вашими собственными переменными.
мой немного меньше и проще:
/// <summary> /// Runs a PowerShell script taking it's path and parameters. /// </summary> /// <param name="scriptFullPath">The full file path for the .ps1 file.</param> /// <param name="parameters">The parameters for the script, can be null.</param> /// <returns>The output from the PowerShell execution.</returns> public static ICollection<PSObject> RunScript(string scriptFullPath, ICollection<CommandParameter> 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; }
для меня наиболее гибким способом запуска сценария PowerShell из C# было использование PowerShell.Создавать.)(AddScript()
фрагмент кода
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<User>(); foreach (var errorRecord in _powershell.Streams.Error) Console.WriteLine(errorRecord);
вы можете проверить, есть ли какие-либо ошибки, проверяя потоки.Ошибка. Это было очень удобно, чтобы проверить коллекцию. Пользователь-это тип объекта, возвращаемого сценарием PowerShell.