我试图在c#中运行powershell脚本。程序运行成功但不显示任何输出

时间:2015-07-23 02:41:44

标签: c# powershell

我正在尝试在c#中运行powershell脚本。程序运行成功但不显示任何输出。

try
{
    string fileName = "D:\\Script\\script.psm1";

    RunspaceConfiguration config = RunspaceConfiguration.Create();
    Runspace myRs = RunspaceFactory.CreateRunspace(config);
    myRs.Open();

    RunspaceInvoke scriptInvoker = new RunspaceInvoke(myRs);
    scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
    /*using (new Impersonator("myUsername", "myDomainname", "myPassword"))
    {
        using (RunspaceInvoke invoker = new RunspaceInvoke())
        {
            invoker.Invoke("Set-ExecutionPolicy Unrestricted");
        }
    } */
    Pipeline pipeline = myRs.CreatePipeline();
    pipeline.Commands.AddScript(fileName);
    //...
    pipeline.Invoke();
    var error = pipeline.Error.ReadToEnd();

    myRs.Close();
    string errors = "";
    if (error.Count >= 1)
    {

        foreach (var Error in error)
        {
            errors = errors + " " + Error.ToString();
        }
    }
    return errors;
}

2 个答案:

答案 0 :(得分:0)

您的程序仅检查错误输出。您通常会将“标准”输出作为Invoke方法的返回值,例如

Collection<PSObject> results = pipeline.Invoke();
string output = "";
foreach (var result in results)
{
    output += result.ToString();
}

答案 1 :(得分:-1)

你并没有对那些包裹着所有内容的大try {}块做任何好处,因为你无法看到正在发生的异常。

您需要以本地管理员身份运行Visual Studio才能实现&#34; Set-ExecutionPolicy Unrestricted&#34;为了工作,最终的可执行文件也将具有该要求,因为发出该命令需要访问受保护的注册表项。

pipeline.Invoke()方法返回类型Collection<PSObject>

Collection<PSObject> results = pipeLine.Invoke();

如果您的意图是忽略管道的输出而只看错误,那很好;但是如果脚本中没有错误,那么通常不会看到任何错误。

使用脚本上的.psm1文件扩展名,您可能会获得null结果。正确的扩展名应为.ps1.psm1扩展名适用于存储在文件系统上特殊位置且自动加载的模块(在PowerShell 3.0 +中)。

默认情况下,&#39;停止&#39; PowerShell中的类型错误将在C#程序中生成异常,因此使用try / catch包装是查看它们的一种方法。

Collection<PSObject> results = null;
try
{
    results = pipeline.Invoke();
    // results returned from PowerShell can be accessed here but may not
    // necessarily be valid since a 'Continue' error could have occurred
    // which would not generate an exception
}
catch (RuntimeException e)
{
    Debug.WriteLine("Error: " + e.Message);
}

您可以通过在script.ps1中添加以下内容来测试:

throw "This is an error"

工作示例:

注意: 1.您需要添加对System.Management.Automation.dll的引用才能运行此代码示例。如果您使用的是Visual Studio,则可以选择“添加引用”,然后选择“浏览...”按钮,并在“浏览”对话框的搜索框中输入程序集的名称,它可能会显示在搜索结果中。如果不是,您可能需要下载Windows SDK的.NET部分。 2.默认情况下,Windows中禁用PowerShell脚本,这是运行PowerShell脚本的代码。有关网络的大量信息,但启用脚本的标准方法是以本地管理员身份打开PowerShell命令提示符并运行Set-ExecutionPolicy RemoteSigned(如果需要,可以使用Unrestricted而不是RemoteSigned) 。 3.在某些环境中,您需要通过右键单击Windows资源管理器中的文件,转到“属性”,然后单击“取消阻止”来取消阻止从Internet下载的脚本。如果没有取消阻止按钮,则文件正常。 4.如果出现访问错误,首先要尝试的是以本地管理员身份运行Visual Studio和/或可执行文件。请勿尝试模拟管理员并在可执行文件中嵌入密码。如果您处于公司设置,则可以将组策略配置为允许运行PowerShell脚本。如果您在家,您应该是本地管理员。

using System.Management.Automation;
using System.Collections.ObjectModel;
using System.Management.Automation.Runspaces;
using System.Diagnostics;

namespace PowerShell
{
    class Program
    {
        static void Main(string[] args)
        {
            // Create and Open a Runspace
            string fileName = @"D:\script.ps1";
            RunspaceConfiguration config = RunspaceConfiguration.Create();
            Runspace myRs = RunspaceFactory.CreateRunspace(config);
            myRs.Open();

            // Attempt to configure PowerShell so we can forcefully run a script.
            RunspaceInvoke scriptInvoker = new RunspaceInvoke(myRs);
            scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted -Scope Process -Force");

            Pipeline pipeline = myRs.CreatePipeline();
            pipeline.Commands.AddScript(fileName);

            Collection<PSObject> results = null;
            try
            {
                results = pipeline.Invoke();

                // Read standard output from the PowerShell script here...
                foreach (var item in results)
                {
                    Debug.WriteLine("Normal Output: " + item.ToString());
                }
            }
            catch (System.Management.Automation.RuntimeException e)
            {
                Debug.WriteLine("PowerShell Script 'Stop' Error: " + e.Message);
            }

            myRs.Close();
        }
    }
}