无法从 C# 调用 Powershell 函数

Posted

技术标签:

【中文标题】无法从 C# 调用 Powershell 函数【英文标题】:Unable to call a Powershell function from C# 【发布时间】:2021-08-31 06:56:27 【问题描述】:

C#代码: C#代码无法调用powershell脚本中存在的函数Trial2,尽管它之前正在执行。

    StringBuilder sb = new StringBuilder();
    PowerShell psExec = PowerShell.Create();
    psExec.AddScript(@ "C:\Users...\sc.ps1");
    psExec.AddCommand("Trial2").AddParameter("a", "Ram");
    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());

Powershell 脚本:

function Trial2($a)
    "Yes! $a";

我得到的错误:

我在 Powershell 中也将 Set-ExecutionPolicy 设置为 Unrestricted。

提前致谢!

【问题讨论】:

您可以尝试“Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine”...它将适用于所有用户并且在没有配置文件的情况下运行 psExec.AddScript("Set-ExecutionPolicy")更改为psExec.AddCommand("Set-ExecutionPolicy"),然后在下一行调用AddScript(...)之前调用AddStatement() 这能回答你的问题吗? PowerShell says "execution of scripts is disabled on this system." 另外,请不要将错误发布为图片,请 psExec.AddScript(@"C:\Users...\sc.ps1") 更改为psExec.AddScript(@ ". 'C:\Users...\sc.ps1'")(注意前面的.)——这将点源脚本而不是仅仅在它自己的范围内执行它 【参考方案1】:

Mathias R. Jessen 在他的 cmets 中提供了所有必要的指针,但让我把它们放在一起:

PowerShell psExec = PowerShell.Create();

// Add a script block that dot-sources (.) your .ps1 file,
// which in turn defines the Trial2 function.
psExec.AddScript(@". C:\Users...\sc.ps1");

// Start a new statement to ensure that the dot-sourcing is performed
// before additional commands are executed.
psExec.AddStatement();

// Now you can add a command that calls your Trial2 function.
psExec.AddCommand("Trial2").AddParameter("a", "Ram");

// ...

请注意,API 是流畅的,因此您可以使用 single 语句;下面演示了这一点,还展示了如何直接通过 API 设置执行策略,而不是像您最初尝试的那样通过提交 Set-ExecutionPolicy 命令:

// Create an initial default session state.
var iss = System.Management.Automation.Runspaces.InitialSessionState.CreateDefault2();
// Set its script-file execution policy.
iss.ExecutionPolicy = Microsoft.PowerShell.ExecutionPolicy.Bypass;

// Create a PowerShell instance with a runspace based on the 
// initial session state.
PowerShell psExec = PowerShell.Create(iss);

psExec
  .AddScript(@". C:\Users...\sc.ps1")
  .AddStatement()
  .AddCommand("Trial2").AddParameter("a", "Ram");

// ...

请注意,以这种方式设置执行策略等同于使用Set-ExecutionPolicy -Scope Process 进行设置。这意味着它将对从当前进程启动的所有 PowerShell 会话保持有效

【讨论】:

以上是关于无法从 C# 调用 Powershell 函数的主要内容,如果未能解决你的问题,请参考以下文章

从 C# 应用程序的脚本中调用 PowerShell 函数

从 PowerShell 调用时无法在 dll 中转换透明代理,但在 C# 控制台应用程序中成功

从 Powershell 调用带有数组参数的构造函数

从 C# PowerShell cmdlet 返回退出代码

如何从 C# 文件调试“调用”Powershell (ps1)

从 C# 异常调用的 PowerShell AddCommand