【问题标题】:Execute PowerShell Script from C# MVC Web Application从 C# MVC Web 应用程序执行 PowerShell 脚本
【发布时间】:2016-03-22 16:53:39
【问题描述】:

我需要从我的 asp.net MVC Web 应用程序中执行一个 powershell 脚本。我的要求是动态创建网站集。我有它的脚本,它工作得很好。没有要传递给脚本的参数。我一直在使用的代码如下所示:

RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();

Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();

RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);

Pipeline pipeline = runspace.CreatePipeline();

//Here's how you add a new script with arguments
Command myCommand = new Command(scriptfiellocation);

pipeline.Commands.Add(myCommand);
pipeline.Commands.Add("Out-String");

// Execute PowerShell script
var result = pipeline.Invoke();

在执行代码时,当我检查变量结果的计数时,它给出的计数为 1。但是在检查我的网站时,没有创建任何网站集。我无法确定哪里出错了,因为没有运行时错误,并且 Invoke 命令似乎也运行正常。

谁能告诉我我可能会在哪里失控?考虑到 PowerShell 脚本在通过管理 shell 运行时可以完美运行。

【问题讨论】:

  • 可能是权限问题。运行站点的帐户是否具有所需的权限?在 Invoke 操作之后检查管道的状态。
  • 操作结束后,管道状态显示为 Completed。是的,该帐户也具有所需的权限。关于还有什么可能导致问题的任何想法?

标签: c# asp.net-mvc powershell scripting


【解决方案1】:

我不得不放弃管道方法,因为我无法弄清楚问题出在哪里。该方法的另一个问题是它引发了错误:“Get-SPWbTemplate 未被识别为 cmdlet”。以下代码对我来说非常好用,并创建了所需的网站集:

 PowerShell powershell = PowerShell.Create();
                    //RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
                    //Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration)
                    using (Runspace runspace = RunspaceFactory.CreateRunspace())
                    {
                        runspace.Open();
                        //RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
                        //scriptInvoker.Invoke("Set-ExecutionPolicy Unrestricted");
                        powershell.Runspace = runspace;
                       //powershell.Commands.AddScript("Add-PsSnapin Microsoft.SharePoint.PowerShell");
                        System.IO.StreamReader sr = new System.IO.StreamReader(scriptfilepath);
                        powershell.AddScript(sr.ReadToEnd());
                        //powershell.AddCommand("Out-String");
                        var results = powershell.Invoke();
                        if (powershell.Streams.Error.Count > 0)
                        {
                            // error records were written to the error stream.
                            // do something with the items found.
                        }
                    }

也不需要设置执行策略。

【讨论】:

    【解决方案2】:

    不知道它是否有帮助,但我从不使用管道来运行命令 shell,不确定它是如何工作的。

    这里是一个简单的例子

        Runspace RS = RunspaceFactory.CreateRunspace(myConnection);
        PowerShell PS = PowerShell.Create();
    
          PSCommand PScmd = new PSCommand();
            string cmdStr = "Enable-Mailbox -Identity " + username + " -Database DB01 -Alias " + aliasexample;
            PScmd.AddScript(cmdStr);
    
        try
        {
            RS.Open();
            PS.Runspace = RS;
            PS.Commands = PScmd;
            PS.Invoke();
        }
        catch (Exception ex)
        {
            ex.ToString();
        }
        finally
        {
            RS.Dispose();
            RS = null;
            PS.Dispose();
            PS = null;
        }
    

    如果出现问题,您可以通过 try catch 捕获错误。 如果我没记错的话,我必须放 ACL.exe 以获得文件系统的权限,这样我才能执行命令外壳,你可以在谷歌上快速搜索它。 希望对您有所帮助。

    【讨论】:

    • 我确实使用了 try catch 块。但是它永远不会进入 catch 块。因此我无法弄清楚哪里出了问题!!!
    • 就像我说不确定如何使用管道,所以我不能告诉你,但通过检查类你可能会这样做 var error = pipeline.Error.Read() as Collection而不是验证它是否为空,然后迭代它以检查错误,如果不是可能与权限有关的东西或像我这样的系统中缺少某些文件,我在我的主机上使用 Acl 来运行 powershell 命令权限。在 Web 应用程序中执行命令 shell 可能会很棘手。
    猜你喜欢
    • 2019-09-15
    • 2017-11-18
    • 2023-03-07
    • 2018-11-09
    • 2014-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多