在C#中运行powershell,没有太多运气!

时间:2011-02-28 15:16:13

标签: c# asp.net powershell

我创建了一个供内部使用的asp.net Web应用程序,允许某些用户启动和停止链接到QA测试环境的虚拟机,后面的代码运行一个PowerShell脚本,一旦按钮启动所选服务器在ASP.net页面上按下。

我已经研究过这个网站上的很多代码,但是我遇到了一些问题。

每次我点击主网页上的按钮时,从powershell脚本反馈的错误都说“你不能在空值表达式上调用方法”。唯一的问题是,如果我从像这样的“。\ script \ test.ps1'W7EA9'这样的PowerShell提示符运行它,它可以正常工作。

这是调用powershell脚本的类。

    public String Startserver(String Servername)
    {

        String scriptText =". \\scripts\\test.ps1 " + Servername + "";


        // create Powershell runspace
        Runspace runspace = RunspaceFactory.CreateRunspace();
        // open it
        runspace.Open();

        // create a pipeline and feed it the script text
        Pipeline pipeline = runspace.CreatePipeline();
        pipeline.Commands.AddScript(scriptText);


        // execute the script
        Collection<PSObject> results = new Collection<PSObject>();

        try
        {
            results = pipeline.Invoke();
        }
        catch (Exception ex)
        {
            results.Add(new PSObject((object)ex.Message));
        }

        // close the runspace
        runspace.Close();

        // convert the script result into a single string
        StringBuilder stringBuilder = new StringBuilder();

        foreach (PSObject obj in results)
        {

            stringBuilder.AppendLine(obj.ToString());

        }

        return stringBuilder.ToString();
        //return scriptText;
    }

这是它试图运行的powershell脚本

    Param ($server = $arg[0])

    $Core = get-wmiobject -namespace root\virtualization -class Msvm_Computersystem -filter "ElementName = '$server'"
    $status = $Core.RequestStateChange(2) `

这可能是一件非常明显的事情,但我只是没有看到它,任何帮助都会很棒。

谢谢

克里斯

5 个答案:

答案 0 :(得分:3)

以下是从ASP.NET运行PowerShell的最佳分步指南。

http://devinfra-us.blogspot.com/2011/02/using-powershell-20-from-aspnet-part-1.html

HTH

答案 1 :(得分:0)

我没有看到你在哪里为脚本提供参数。

答案 2 :(得分:0)

我正在通过asp.net页面上的按钮按下传递参数,后面的代码看起来像这样

        Hypervserver Start = new Hypervserver();

        String result = Start.Startserver("W7EA9");

        Label1.Visible = true;
        Label1.Text = result;

答案 3 :(得分:0)

以下是我最终如何做到这一点。

Runspace runspace = RunspaceFactory.CreateRunspace();
runspace.Open();
Pipeline pipeline = runspace.CreatePipeline();

Command myCommand = new Command("C:\\Scripts\\Test.ps1");
//I used full path name here, not sure if you have to or not 

CommandParameter myParam1 = new CommandParameter("-ServerName", "myServer");
myCommand.Parameters.Add(myParam1);
//You can add as many parameters as you need to here

pipeline.Commands.Add(myCommand);

Collection<PSObject> results = pipeline.Invoke();
runspace.Close();

StringBuilder stringBuilder = new StringBuilder()
foreach (PSObject obj in results) {
    stringBuilder.AppendLine(obj.ToString());
}
string thestring = stringBuilder.ToString();

一些笔记。不是注释或空行的脚本第一行应该是如下格式的参数列表:

param([string]$ServerName,[string]$User)

你有这个,我只是想承认,当我的脚本文件是带参数的函数时,我无法正常工作。

对于某些命令,您可能需要其他权限,在我的情况下,我的所有脚本都以这种方式工作,除了创建一个我必须在连接上添加凭据的邮箱。

格雷格

答案 4 :(得分:0)

在powershell中,默认参数集合称为$ args,其中包含&#39 ;;我非常肯定,当你通过代码运行$ server时,$ server为null,因此Get-WmiObject调用返回null,当你尝试在其上调用RequestStateChange方法时导致错误。

我猜你在普通的PowerShell窗口中工作正常,因为你在会话中已经有了一个$ server变量。