首页 文章

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

提问于
浏览
87

我需要在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可以是类似于也可能包含空格的路径 .

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

7 回答

  • 4

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

    Command myCommand = new Command(scriptfile);
    

    然后你可以添加参数

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

    最后

    pipeline.Commands.Add(myCommand);
    

    Here is the complete, edited code:

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

    我有另一个解决方案 . 我只想测试执行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
    
  • 27

    有没有机会我可以更清楚地了解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();
    }
    
  • 8

    您也可以使用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;
    

    它将采用一个字符串,以及您传递的任何参数 .

  • 3

    如果您使用,这是一种向脚本添加参数的方法

    pipeline.Commands.AddScript(Script);
    

    这是使用HashMap作为参数,键是脚本中变量的名称,值是变量的值 .

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

    而fill变量方法是:

    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建议脚本变量列表不会填充你自己的变量 .

  • 2

    我的更小更简单:

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

    对我来说,从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脚本返回的对象类型 .

相关问题