我对 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>
运行它,您应该在页面上看到类似这样的内容:
注意
您可能会找到您的Get-BrokerSession
cmdlet 返回特定类型对象的集合,而不是 PSCustomObject,在这种情况下,您可以跳过转换步骤并将数据直接绑定(bind)到 results
对象,所以你可能需要玩一下才能看到。如果存在任何差异,希望以上内容能为您提供一些提示。
希望这有帮助。
关于c# - 将 powershell 脚本的输出绑定(bind)到 asp.net c# 中的 gridview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60432190/