使用 C# 执行第 3 方 Powershell SDK 命令

Executing 3rd Party Powershell SDK commands with C#

这是一个令人难以置信的令人沮丧的问题,其他人似乎都没有答案,所以我试图将我的问题分解为最简单的问题。当然还有其他第 3 方 Powershell SDK 在那里人们试图通过 C# 访问和使用。有谁知道为什么这会出现以下错误?

The term 'add-PSSnapin Citrix*.Admin.V* is not recognized as the name of a cmdlet, function, script file, or operable program.

此 PSSnapin 在命令提示符下提供的其他命令也是如此。

我可以在 powershell 命令提示符下手动键入此命令并且它有效。其他命令也是如此。怎么回事?

public void testPS()
        {
            using (Runspace runspace = RunspaceFactory.CreateRunspace())
            {
                runspace.Open();
                PowerShell ps = PowerShell.Create();
                ps.Runspace = runspace;
                ps.AddCommand("add-PSSnapin Citrix.*.Admin.V*");
                ps.Invoke();
                //Commented sections below don't work either, same error. 
                //ps.AddCommand("Get-BrokerSession");
                //ps.AddParameter("AdminAddress");
                //ps.AddParameter("SERVERNAME");
                //ps.Invoke();
                //Collection<PSObject> psr = ps.Invoke();
                //foreach (PSObject x in psr)
                //{
                //    MessageBox.Show(x.ToString());
                //}
            }
        }

更新:

下面答案中建议的新代码出现新错误:'System.Management.Automation.ParameterBindingException' occurred in System.Management.Automation.dll

public void testPS()
        {
            using (Runspace runspace = RunspaceFactory.CreateRunspace())
            {
                runspace.Open();
                PowerShell ps = PowerShell.Create();
                ps.Runspace = runspace;
                PSSnapInException psex;
                runspace.RunspaceConfiguration.AddPSSnapIn("Citrix.Broker.Admin.V2", out psex);
                Pipeline pipeline = runspace.CreatePipeline();

                Command getSession = new Command("Get-BrokerSession");
                getSession.Parameters.Add("AdminAddress");
                getSession.Parameters.Add("MYSERVERNAME");
                //also tried the above with this code
                //getSession.Parameters.Add("-AdminAddress MYSERVERNAME");
                // and
                //getSession.Parameters.Add("AdminAddress MYSERVERNAME");
                // and other methods as well
                pipeline.Commands.Add(getSession);

                //This line below is where the exception occurs.
                Collection<PSObject> output = pipeline.Invoke();

                foreach (PSObject x in output)
                {
                    MessageBox.Show(x.ToString());
                }
            }
        }

更新 2:

我在尝试设置执行策略时也遇到了同样的错误。

更新 3:

已修复,请参阅下面答案中的评论。参数行的语法不正确。

您需要确保将命令与其参数分开。在你的情况下,它会是这样的:

ps.AddCommand("add-PSSnapin");

然后你总是可以 post-append Citrix.*.Admin.V* 作为上面命令的参数。

使用RunspaceConfiguration.AddPSSnapIn添加PSSnapin然后添加命令:

        Runspace runSpace = RunspaceFactory.CreateRunspace();
        runSpace.Open();
        PSSnapInException psex;
        runSpace.RunspaceConfiguration.AddPSSnapIn("Citrix.Broker.Admin.V2", out psex);
        Pipeline pipeline = runSpace.CreatePipeline();

        Command getSession = new Command("Get-BrokerSession");
        getSession.Parameters.Add("AdminAddress", "SERVERNAME");
        pipeline.Commands.Add(getSession);

        Collection<PSObject> output = pipeline.Invoke();

对于那些像我一样仍然坚持这个问题的人,即使是最新的 Microsoft.Powershell.Sdk 6.2.0 nuget 包,我也在 运行 关注这个问题。我的一位同事最终通过执行以下操作使其正常工作:

    public string RunPowershell(string param1)
    {
        var outputString = "";

        var startInfo = new ProcessStartInfo
        {
            FileName = @"powershell.exe",
            Arguments = "C:\path\to\script.ps1" + " -param1  " + param1,
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            UseShellExecute = false,
            CreateNoWindow = true
        };

        using (var process = new Process())
        {
            process.StartInfo = startInfo;
            process.Start();

            var output = process.StandardOutput.ReadToEnd();
            var errors = process.StandardError.ReadToEnd();

            if (!string.IsNullOrEmpty(output))
            {
                outputString = output;
            }

            if (!string.IsNullOrEmpty(errors))
            {
                Console.WriteLine($"Error: {errors}");
            }
        }

        return outputString;
    }

"C:\path\to\script.ps1" 中可以包含 Add-PSSnapin 个命令,并且仍然 运行 就好了。

我找不到为 Microsoft.Powershell.Sdk 提交的错误来处理此问题,但如果有人创建了一个错误并将其链接到此处,谢谢!

希望对您有所帮助