使用命令行参数从C#执行PowerShell脚本
我需要从C#中执行一个PowerShell脚本。 该脚本需要命令行参数。
这是我迄今为止所做的:
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 Files \ MyProgram \ Whatever.ps1”之类的东西。
该脚本使用命令行参数(如“-key Value”),而Value可以是可能包含空格的path。
我没有得到这个工作。 有谁知道如何将命令行parameter passing给C#中的PowerShell脚本,并确保空间没有问题?
尝试创build脚本文件作为一个单独的命令:
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();
我有另一个解决scheme。 我只是想testing一下,如果执行PowerShell脚本成功,因为也许有人可能会改变政策。 作为参数,我只是指定要执行的脚本的path。
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
任何机会,我可以得到更多的Commands.AddScript方法传递参数的清晰度?
C:\ Foo1.PS1 Hello World Hunger C:\ Foo2.PS1 Hello World
scriptFile =“C:\ Foo1.PS1”
参数=“parm1 parm2 parm3”…可变长度params
解决了这个…传递null作为名称和参数作为值的CommandParameters集合
这里是我的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<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方法使用pipe道:
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;
它将采取一个string,并通过它的任何参数。
如果您使用了以下方法,可以将Paramaters添加到脚本中
pipeline.Commands.AddScript(Script);
这是使用HashMap作为参数,键是脚本中variables的名称,值是variables的值。
pipeline.Commands.AddScript(script)); FillVariables(pipeline, scriptParameter); Collection<PSObject> results = pipeline.Invoke();
而填充variables的方法是:
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); } } }
这样您可以轻松地将多个参数添加到脚本中。 我也注意到,如果你想从你的脚本中获得一个variables的值,就像这样:
Object resultcollection = runspace.SessionStateProxy.GetVariable("results");
//结果是v的名字
你必须按照我所展示的方式来做,因为如果你这样做,Kosi2801build议脚本variables列表没有被你自己的variables填充。
对我来说,从C#运行PowerShell脚本最灵活的方法是使用PowerShell.Create()。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);
您可以通过检查Streams.Error来检查是否有任何错误。 检查收集真的很方便。 用户是powershell脚本返回的对象的types。
矿是更小,更简单:
/// <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; }