c# - 将 powershell 脚本的输出绑定(bind)到 asp.net c# 中的 gridview

标签 c# asp.net powershell gridview data-binding

我对 C# 很陌生,我希望我想做的事情非常简单,但我无法找到或遵循其他示例,其中 powershell 数组的输出填充 gridview 以进行进一步操作/执行另一个脚本。页面加载的过程是运行一个 powershell 脚本,该脚本创建一组填充 GridView 的 session 详细信息。然后可以启动第二个脚本,通过选择 gridview 行来与该 session 进行交互(例如强制注销)。

使用其他示例,我成功启动了第一个 powershell 执行,它将数据通过以下方式发送到表单:

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="PowerShellExecution.Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
     <div>
           <h1>PowerShell Harness<asp:Label ID="Label1" runat="server" Text="Label" Visible="False"></asp:Label>
           </h1>
           <asp:TextBox ID="ResultBox" TextMode="MultiLine" Width="1000px" Height="400px" runat="server"></asp:TextBox>
    </div>
</asp:Content>

隐藏代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Management.Automation;
using System.Text;

namespace PowerShellExecution
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
          // Gets the name if authenticated.
                if (User.Identity.IsAuthenticated)
                    Label1.Text = User.Identity.Name;
                else
                    Label1.Text = "No user identity available.";

            // Clean the Result TextBox
            ResultBox.Text = string.Empty;

            // Initialize PowerShell engine
            var shell = PowerShell.Create();

            // Add the script to the PowerShell object
            // shell.Commands.AddScript(Input.Text);
            // shell.Commands.AddScript("D:\\Local_Scripts\\sessioncall.ps1");
            shell.Commands.AddCommand("c:\\Local_Scripts\\sessioncall.ps1");

            // Add Params
            // shell.Commands.AddParameter(null,User.Identity.Name);
            // shell.Commands.AddParameter("Username", Label1.Text);
            shell.Commands.AddArgument(User.Identity.Name);

            // Execute the script
            var results = shell.Invoke();

            // display results, with BaseObject converted to string
            // Note : use |out-string for console-like output
            if (results.Count > 0)
            {
                // We use a string builder ton create our result text
                var builder = new StringBuilder();

                foreach (var psObject in results)
                {
                    // Convert the Base Object to a string and append it to the string builder.
                    // Add \r\n for line breaks
                    builder.Append(psObject.BaseObject.ToString() + "\r\n");
                }

                // Encode the string in HTML (prevent security issue with 'dangerous' caracters like < >
                ResultBox.Text = Server.HtmlEncode(builder.ToString());
            }

        }
    }
}

Sessioncall.ps1

$SessionUser = "$($args[0])"
set-brokersite -AdminAddress UKSite 
$a = @(Get-BrokerSession -BrokeringUserName $SessionUser | Select-Object UserFullName, BrokeringTime, ClientName,DesktopGroupName, sessionstate, uid, machinename,@{Name='ENV';Expression={'UK'}})
#Pull US Sessions into array
Set-brokersite -AdminAddress USSite
$a += @(Get-BrokerSession -BrokeringUserName $SessionUser | Select-Object UserFullName, BrokeringTime, ClientName,DesktopGroupName, sessionstate, uid, machinename,@{Name='ENV';Expression={'US'}})

If ($a -ne $null){
    Write-Output $a | out-string
}
Else {
    Write-Output "No User session! Username was $SessionUser"
}

当前输出作为输出字符串扔到文本框。我什至正在努力解决如何开始将数组输出数据绑定(bind)为 GridView 中的行。只需要一点指导即可开始!

提前致谢! 保罗。

最佳答案

自从我涉足 WebForms 以来已经有一段时间了,但我找到了一种方法来完成您想要的事情......

首先,让我们稍微更改一下您的 PowerShell 脚本。我们可以简单地返回对象,而不是返回字符串(这就是| out-string正在做的事情)。 shell.Invoke() C# 代码中的方法知道如何从脚本的输出中提取成熟的对象,因此我们不需要序列化为 PowerShell 脚本内的字符串,然后尝试再次将其反序列化回 C# 代码内的对象。

暂时忽略您的业务线逻辑,我的脚本只是返回 PSCustomObjects 数组,如下所示:

MyScript.ps1

write-output @(
    (new-object PSCustomObject -Property ([ordered] @{
         "MyProperty1" = "MyValue1.1"
         "MyProperty2" = "MyValue2.1"
         "MyProperty3" = "MyValue3.1"
    })),
    (new-object PSCustomObject -Property ([ordered] @{
          "MyProperty1" = "MyValue1.2"
          "MyProperty2" = "MyValue2.2"
          "MyProperty3" = "MyValue3.2"
    }))
);

现在,我的 C# Page_Load 方法执行以下操作:

默认.aspx.cs

protected void Page_Load(object sender, EventArgs e)
{

    // Initialize PowerShell engine
    var powershell = PowerShell.Create();

    // Add the script to the PowerShell object
    var script = "c:\\temp\\MyScript.ps1";
    powershell.Commands.AddCommand(script);

    // Execute the script
    var results = powershell.Invoke();

    ...

results包含 System.Collections.ObjectModel.Collection<PSObject> 。我们无法将其直接数据绑定(bind)到 GridView,因为这些属性隐藏在 Properties 中的键值对内。每个PSObject的成员,但是如果我们创建一个新类,则可以很容易地将值提取到我们可以数据绑定(bind)的内容中:

MyClass.cs

public class MyClass
{
    public string MyProperty1 { get; set; }
    public string MyProperty2 { get; set; }
    public string MyProperty3 { get; set; }
}

我们的 Page_Load 可以将 PSObject 转换为此类的实例:

默认.aspx.cs

    ...

    var objects = results.Select(
        r => new MyClass
        {
            MyProperty1 = (string)r.Properties["MyProperty1"].Value,
            MyProperty2 = (string)r.Properties["MyProperty2"].Value,
            MyProperty3 = (string)r.Properties["MyProperty3"].Value,
        }
    );

    this.ResultGrid.DataSource = objects;
    this.ResultGrid.DataBind();

}

然后,要显示数据,您只需将 GridView 添加到 Default.aspx 中,并使用您想要定义的任何列和格式:

默认.aspx

<%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
     <div>
           <h1>PowerShell Harness<asp:Label ID="Label1" runat="server" Text="Label" Visible="False"></asp:Label></h1>
            <asp:GridView ID="ResultGrid" runat="server" AutoGenerateColumns="false">
                <Columns>
                    <asp:BoundField DataField="MyProperty1" HeaderText="My Property 1" />
                    <asp:BoundField DataField="MyProperty2" HeaderText="My Property 2"  />
                    <asp:BoundField DataField="MyProperty3" HeaderText="My Property 3"  />
                </Columns>
            </asp:GridView>
    </div>
</asp:Content>

运行它,您应该在页面上看到类似这样的内容:

ASP.Net page with GridView bound from a PowerShell script

注意

您可能会找到您的Get-BrokerSession cmdlet 返回特定类型对象的集合,而不是 PSCustomObject,在这种情况下,您可以跳过转换步骤并将数据直接绑定(bind)到 results对象,所以你可能需要玩一下才能看到。如果存在任何差异,希望以上内容能为您提供一些提示。

希望这有帮助。

关于c# - 将 powershell 脚本的输出绑定(bind)到 asp.net c# 中的 gridview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60432190/

相关文章:

javascript - 如何使用javascript修改gridview单元格值

c# - Aes 加密...缺少一个重要部分

c# - 在 C# 中返回对象的 JSON 数组

asp.net - VB.NET 跟踪变量

asp.net - 填充数据并更新行后,更改 DataTable 的 DataColumn 的 DataType

powershell - 在foreach循环中重用变量

c# - return 语句可以阻止 using 语句关闭与数据库的连接吗?

c# - Reflection.Emit 和 Parallel.ForEach

windows - 静默安装 Sublime

powershell - Connect-ServiceFabricCluster 在 "Reset local cluster"之后不起作用