【问题标题】:Running powershell in C#, not having much luck!在 C# 中运行 powershell,运气不好!
【发布时间】:2014-07-29 00:27:03
【问题描述】:

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

我已经从这个网站上研究和实施了很多代码,但我遇到了一些问题。

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

这是调用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) `

这可能很明显,但我只是没有看到它,任何帮助都会很棒。

谢谢

克里斯

【问题讨论】:

  • 后面的代码将尝试在服务器中运行 powershell 命令。这是你要找的吗?
  • 您确定将正确的 ServerName 传递给函数吗?
  • 嗨,我希望在站点所在的服务器上运行脚本,我已经在我的机器上调试了应用程序,并且服务器名称在传递给 powershell 之前在字符串中传递跨度>
  • 为什么在字符串末尾有“”?这还不够吗? String scriptText =". \\scripts\\test.ps1 " + Servername;
  • 好点,我会改变它,看看效果如何

标签: c# asp.net powershell


【解决方案1】:

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

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

HTH

【讨论】:

  • 我已经成功使用 System.Management.Automation 自己运行 PowerShell 脚本(尽管来自 Windows 服务)
  • 我已经查看了这个并做了一些调整,看起来 powershell 代码在服务器上没有正确运行,我可以运行一个 get 进程 |输出字符串并取回数据,但服务器重启不会运行,但它会直接从 powershell 运行
  • 与执行策略有关。只是猜测。
  • 执行策略设置为无限制,因为这是我在 Hyperv 环境中部署之前的测试服务器
  • 对我来说,您的参数传递方式似乎有些问题。该错误实际上意味着没有创建 WMI 对象。
【解决方案2】:

我看不到您在哪里为脚本提供参数。

【讨论】:

  • Hypervserver 启动 = new Hypervserver();字符串结果 = Start.Startserver("W7EA9");标签1.可见=真; Label1.Text = 结果;
  • 我的意思不是你如何将参数传递给 C# 代码,而是你如何将参数(在本例中为 W7EA9)传递给 powershell 脚本。您有一个参数语句 ($server = $arg[0]),但我没有看到 C# 代码将参数传入。不过,我可能只是错过了它。
  • 嗨,对不起,意思是发布这样的信息,将变量传递给powershell的脚本部分以“String scriptText =”开头。 \\scripts\\test.ps1 " + Servername + "" 然后通过代码 pipeline.Commands.AddScript(scriptText); 添加到管道中,然后通过代码调用 results = pipeline.Invoke();
【解决方案3】:

我在 asp.net 页面上按下按钮传递参数,后面的代码如下所示

        Hypervserver Start = new Hypervserver();

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

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

【讨论】:

    【解决方案4】:

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

    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)
    

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

    对于某些命令,您可能需要额外的权限,就我而言,我的所有脚本都以这种方式工作,除了创建一个邮箱,我必须为其添加凭据到连接。

    格雷格

    【讨论】:

      【解决方案5】:

      在 powershell 中,默认的参数集合称为 $args,带有一个 's';我很确定这就是为什么当您通过代码运行 $server 时它为 null 的原因,因此 Get-WmiObject 调用返回 null,当您尝试对其调用 RequestStateChange 方法时导致错误。

      我猜它在您的普通 powershell 窗口中可以正常工作,因为您在会话中已经有一个 $server 变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-23
        • 2018-12-07
        • 1970-01-01
        • 1970-01-01
        • 2018-11-21
        • 2011-03-02
        • 2014-03-18
        • 1970-01-01
        相关资源
        最近更新 更多