使用命令行参数从C#执行PowerShell脚本

Mep*_*toe 91 c# powershell scripting command-line arguments

我需要在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();
Run Code Online (Sandbox Code Playgroud)

scriptFile包含类似"C:\ Program Files\MyProgram\Whatever.ps1"的内容.

该脚本使用命令行参数,例如"-key Value",而Value可以是类似于也可能包含空格的路径.

我不这样做.有谁知道如何从C#中将命令行参数传递给PowerShell脚本并确保空格没有问题?

Kos*_*801 106

尝试将scriptfile创建为单独的命令:

Command myCommand = new Command(scriptfile);
Run Code Online (Sandbox Code Playgroud)

然后你可以添加参数

CommandParameter testParam = new CommandParameter("key","value");
myCommand.Parameters.Add(testParam);
Run Code Online (Sandbox Code Playgroud)

最后

pipeline.Commands.Add(myCommand);
Run Code Online (Sandbox Code Playgroud)

以下是完整的编辑代码:

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();
Run Code Online (Sandbox Code Playgroud)

  • 未使用 scriptInvoker 变量。 (3认同)
  • 没关系。有时,当您知道如何正确拆分字符串时会有所帮助。;-) 再次感谢,您的解决方案帮助我解决了我的问题! (2认同)

Jow*_*wen 30

我有另一种解决方案.我只想测试执行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));
Run Code Online (Sandbox Code Playgroud)

脚本的内容是:

$someVariable = "StringToBeVerifiedInAUnitTest"
$someVariable
Run Code Online (Sandbox Code Playgroud)

  • 你好。您知道为什么按照您的描述启动 powershell 并执行所有命令进程(在我们的例子中)不退出吗? (2认同)

小智 9

有没有机会我可以更清楚地了解Commands.AddScript方法的传递参数?

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

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();
}
Run Code Online (Sandbox Code Playgroud)


And*_*ndy 7

对我来说,从 C# 运行 PowerShell 脚本的最灵活方法是使用PowerShell.Create().AddScript()

首先,您需要安装Microsoft.PowerShell.SDK nuget 包。或者,如果针对 .net 框架,您将需要Microsoft.PowerShell.5.ReferenceAssemblies

代码片段是

using System.Management.Automation;

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);
Run Code Online (Sandbox Code Playgroud)

您可以通过检查Streams.Error来检查是否有任何错误。检查收藏确实很方便。User 是 PowerShell 脚本返回的对象类型。


Jam*_*ran 5

您也可以将管道与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;
Run Code Online (Sandbox Code Playgroud)

它需要一个字符串,以及您传递的任何参数。


小智 5

我的更小更简单:

/// <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;
}
Run Code Online (Sandbox Code Playgroud)