在C#中将命令插入到调用命令中

4
我有大量的命令,不想改变它们。因此,我想将命令对象转换为代码块对象,并将它们的参数添加到调用中,以便以后在另一台计算机上执行它们。
最终结果是以下代码: string server=cpu1.com
    public void ExecuteRemote(Command basis) {

        RunspaceInvoke invoke = new RunspaceInvoke();
        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        Pipeline pipeLine = runspace.CreatePipeline();
        ScriptBlock s=basis.CommandText);//<<<<this does not work, how can I fix this?

        Command invokeScript = new Command("Invoke-Command");

        invokeScript.Parameters.Add("ComputerName", server);
        invokeScript.Parameters.Add("scriptBlock", s);
        invokeScript.Parameters.Join(basis.Parameters); // and this does not work either?

        pipeLine.Commands.Add(invokeScript);
        Collection<PSObject> commandResults = pipeLine.Invoke();
 }

有人知道如何做到这一点吗?

我标记的两行代码无法正常工作(无法编译),我想知道如何修复它们。

    ScriptBlock s=basis.CommandText);//<<<<this does not work, how can I fix this?

应该将基础命令加载到脚本块中,以便稍后用于执行代码。
    invokeScript.Parameters.Join(basis.Parameters); // and this does not work either?

尝试将参数从基础移动到invokescript。
我根据从C#调用远程powershell命令撰写了我的答案,但是由于我无法为每个函数更改参数(有很多命令需要处理),因此我只想取出命令并执行它。
在查看@Keith hill的答案后进行编辑
Console.WriteLine(“创建调用”); RunspaceInvoke invoke = new RunspaceInvoke();
        Runspace runspace = RunspaceFactory.CreateRunspace();
        runspace.Open();
        Console.WriteLine("creating pipeline");

        Pipeline pipeLine = runspace.CreatePipeline();
        Console.WriteLine("creating scriptblock");
        ScriptBlock s = ScriptBlock.Create(basis.CommandText);
        Command invokeScript = new Command("Invoke-Command");
        Console.WriteLine("adding parameter1");
        invokeScript.Parameters.Add("ComputerName", "test1.com");

        invokeScript.Parameters.Add("scriptBlock", s);

        foreach (var p in basis.Parameters)            {

            invokeScript.Parameters.Add(p.Name, p.Value);
        }

        pipeLine.Commands.Add(invokeScript); Console.WriteLine("res");
        Collection<PSObject> commandResults = pipeLine.Invoke();

当我尝试添加以下命令时,出现了找不到名称为“Name”的参数的错误: Command MaakActiveDirectoryOU = new Command("New-ADOrganizationalUnit");


        MaakActiveDirectoryOU.Parameters.Add("Name", KlantNaam);
        MaakActiveDirectoryOU.Parameters.Add("Path", WebConfigurationManager.AppSettings["SharedOU"].ToString());
        ExecuteRemote2(MaakActiveDirectoryOU);

这个命令在本地执行时正常工作,有人知道原因吗?

为什么要踩我?能解释一下吗? - Thijser
现在我很好奇为什么有两个人选择了反对,我认为这是一个很合理的问题? - Thijser
我也不知道 - 这是一个好问题,你清晰地阐述了问题,展示了自己的研究努力,并且问题用非常好的英语问得很好(没有错别字,语言清晰)。我至少点了一次赞以弥补一个未解释的踩的影响..... - marc_s
首先我没有点踩!但我理解为什么有两个踩,因为这个问题真的不清楚:是的,你写了它在哪里失败,但没有说明错误/异常是什么。 - Random Dev
嘿,至少你没有要求别人为你编写脚本,这值得点赞。:-) 话虽如此,在未来,看到一个简单的错误解释是很有帮助的,例如这一行编译时出现了错误 blah,或者在运行时程序抛出了 InvalidCastException 异常。最终,这将帮助你更快地得到更好的答案。 - Keith Hill
1个回答

4

您不能将字符串赋值给ScriptBlock类型的变量。 您需要使用静态的create方法创建脚本块(注意:ScriptBlock构造函数是受保护的,因此无法使用它)例如:

var s = ScriptBlock.Create(command.CommandText);

关于添加参数,可以尝试以下方法:
foreach (var p in basis.Parameters) {
    invokeScript.Parameters.Add(p.Name, p.Value);
}

Join Linq命令可以将两个序列合并,但合并后的序列以Join命令的结果输出。它不会修改原始的两个序列。


基础看起来没问题,但参数有问题,你能看一下吗? - Thijser

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接