【问题标题】:How to pass reference parameter to PowerShell script from C#如何从 C# 将引用参数传递给 PowerShell 脚本
【发布时间】:2020-03-12 18:51:49
【问题描述】:

我似乎无法将引用参数从 C# 传递给 PowerShell。我不断收到以下错误:

“System.Management.Automation.ParentContainsErrorRecordException:无法处理参数'Test'的参数转换。参数中应有引用类型。”

例子:

对于简单的脚本:

Param (
[ref]
$Test
)

$Test.Value = "Hello"
Write-Output $Test

这是 C# 代码:

string script = {script code from above};
PowerShell ps = PowerShell.Create();
ps = ps.AddScript($"New-Variable -Name \"Test\" -Value \"Foo\""); // creates variable first
ps = ps.AddScript(script)
        .AddParameter("Test", "([ref]$Test)"); // trying to pass reference variable to script code

ps.Invoke(); // when invoked, generates error "Reference type is expected in argument

我已经尝试过 AddParameter 以及 AddArgument。

我的工作是首先创建我的脚本作为脚本块:

ps.AddScript("$sb = { ... script code ...}"); // creates script block in PowerShell
ps.AddScript("& $sb -Test ([ref]$Test)"); // executes script block and passes reference parameter
ps.AddScript("$Test"); // creates output that shows reference variable has been changed

有什么帮助吗?

【问题讨论】:

  • 您需要什么帮助?您已经说过/表明您可以使用脚本块解决方法获得结果。为什么要为不同的事情感到压力?为什么你认为使用脚本 blick 是一件坏事?
  • 公平点 - 我应该说我想了解为什么我的第一种方法不起作用,以便更好地理解 PowerShell 的 C# 接口,因为文档非常有限。
  • 但是要注意,@mklement0 的解决方案比我的脚本块方法要好,因为我不必为了知道输出变量而在 PS 中显式输出 [ref] 变量。相反,我可以只检查传递给 AddParameter 的 C# PSReference 对象。
  • 明白。因此,请更新您的帖子以显示您所做的事情,以便其他可能需要相同方法的人清楚。

标签: c# powershell


【解决方案1】:

我似乎无法从 C# 向 PowerShell 传递引用参数

使您的原始方法发挥作用的唯一方法是在 C# 中创建 [ref] 实例 并传递 that,这意味着创建System.Management.Automation.PSReference 的一个实例并将其传递给您的 .AddParameter() 调用:

// Create a [ref] instance in C# (System.Management.Automation.PSReference)
var psRef = new PSReference(null);

// Add the script and pass the C# variable containing the
// [ref] instance to the script's -Test parameter.
ps.AddScript(script).AddParameter("Test", psRef);

ps.Invoke();

// Verify that the C# [ref] variable was updated.
Console.WriteLine($"Updated psRef: [{psRef.Value}]");

以上产生Updated psRefVar: [Hello]


完整代码:

using System;
using System.Management.Automation;

namespace demo
{
  class Program
  {
    static void Main(string[] args)
    {
      var script = @"
        Param (
        [ref]
        $Test
        )

        $Test.Value = 'Hello'
        Write-Output $Test
        ";

      using (PowerShell ps = PowerShell.Create())
      {
        var psRef = new PSReference(null);
        ps.AddScript(script).AddParameter("Test", psRef);
        ps.Invoke();
        Console.WriteLine($"Updated psRef: [{psRef.Value}]");
      }

    }
  }
}

【讨论】:

  • 太棒了-谢谢!说得通。你能解释一下 AddParameter 与 AddArgument 之间的真正区别吗?只是 AddParameter 被命名而 AddArgument 依赖于引用 $args[] 数组的 PS 脚本吗?再次感谢。
  • 很高兴听到它有帮助,@MikeOliver;参数是一个未命名的值(仅仅是一个值,前面没有参数名称),位置传递。为了稳健性,您应该使用.AddParameter()。这能解释清楚吗?
猜你喜欢
  • 2015-06-07
  • 2012-05-05
  • 2014-01-07
  • 2020-09-04
  • 2012-12-10
  • 2021-08-26
  • 2011-08-01
  • 2020-04-04
相关资源
最近更新 更多