如何将参数从C#传递到PowerShell脚本文件?

时间:2012-07-10 01:18:10

标签: powershell

从命令行我可以做到。

.\test.ps1 1

从C#执行此操作时如何传递参数? 我试过了

   .AddArgument(1)
   .AddParameter("p", 1)

我尝试将值传递为IEnumerable< object>在.Invoke()中但是$ p没有得到值。

namespace ConsoleApplication1
{
    using System;
    using System.Linq;
    using System.Management.Automation;

    class Program
    {
        static void Main()
        {
            // Contents of ps1 file
            //  param($p)
            //  "Hello World ${p}"

            var script = @".\test.ps1";

            PowerShell
                .Create()
                .AddScript(script)
                .Invoke().ToList()
                .ForEach(Console.WriteLine);
        }
    }
}

4 个答案:

答案 0 :(得分:5)

这是怎么回事?

static void Main()
{
    string script = @"C:\test.ps1 -arg 'hello world!'";
    StringBuilder sb = new StringBuilder();

    PowerShell psExec = PowerShell.Create();
    psExec.AddScript(script);
    psExec.AddCommand("out-string");

    Collection<PSObject> results;
    Collection<ErrorRecord> errors;
    results = psExec.Invoke();
    errors = psExec.Streams.Error.ReadAll();

    if (errors.Count > 0)
    {
        foreach (ErrorRecord error in errors)
        {
            sb.AppendLine(error.ToString());
        }
    }
    else
    {
        foreach (PSObject result in results)
        {
            sb.AppendLine(result.ToString());
        }
    }

    Console.WriteLine(sb.ToString());
}

这是一个传递DateTime实例的类似版本

static void Main()
{
    StringBuilder sb = new StringBuilder();

    PowerShell psExec = PowerShell.Create();
    psExec.AddCommand(@"C:\Users\d92495j\Desktop\test.ps1");
    psExec.AddArgument(DateTime.Now);

    Collection<PSObject> results;
    Collection<ErrorRecord> errors;
    results = psExec.Invoke();
    errors = psExec.Streams.Error.ReadAll();

    if (errors.Count > 0)
    {
        foreach (ErrorRecord error in errors)
        {
            sb.AppendLine(error.ToString());
        }
    }
    else
    {
        foreach (PSObject result in results)
        {
            sb.AppendLine(result.ToString());
        }
    }

    Console.WriteLine(sb.ToString());
}

答案 1 :(得分:2)

所以,简而言之:使用AddCommand而不是AddScript

答案 2 :(得分:1)

另一种方法是用变量填充运行空间。

    public static string RunPs1File(string filePath, Dictionary<string, object> arguments)
    {
        var result = new StringBuilder();

        using (Runspace space = RunspaceFactory.CreateRunspace())
        {
            space.Open();

            foreach (KeyValuePair<string, object> variable in arguments)
            {
                var key = new string(variable.Key.Where(char.IsLetterOrDigit).ToArray());
                space.SessionStateProxy.SetVariable(key, variable.Value);
            }

            string script = System.IO.File.ReadAllText(filePath);
            using (PowerShell ps1 = PowerShell.Create())
            {
                ps1.Runspace = space;
                ps1.AddScript(script);

                var psOutput = ps1.Invoke();

                var errors = ps1.Streams.Error;
                if (errors.Count > 0)
                {
                    var e = errors[0].Exception;
                    ps1.Streams.ClearStreams();
                    throw e;
                }

                foreach (var line in psOutput)
                {
                    if (line != null)
                    {
                        result.AppendLine(line.ToString());
                    }
                }
            }
        }

        return result.ToString();
    }

答案 3 :(得分:-1)

当前更简单的解决方案是先将脚本读取为字符串。

PowerShell
    .Create()
    .AddScript(File.ReadAllText(script)).AddParameter("p", 1)
    .Invoke().ToList()
    .ForEach(Console.WriteLine);