mirror of
https://github.com/ashstrahle/PowerShellBlazor.git
synced 2025-12-31 19:49:52 +10:00
Init
This commit is contained in:
@@ -1,13 +0,0 @@
|
|||||||
namespace PowerShellBlazor.Data;
|
|
||||||
|
|
||||||
public class WeatherForecast
|
|
||||||
{
|
|
||||||
public DateTime Date { get; set; }
|
|
||||||
|
|
||||||
public int TemperatureC { get; set; }
|
|
||||||
|
|
||||||
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
|
|
||||||
|
|
||||||
public string? Summary { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
namespace PowerShellBlazor.Data;
|
|
||||||
|
|
||||||
public class WeatherForecastService
|
|
||||||
{
|
|
||||||
private static readonly string[] Summaries = new[]
|
|
||||||
{
|
|
||||||
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
|
|
||||||
};
|
|
||||||
|
|
||||||
public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
|
|
||||||
{
|
|
||||||
return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
|
|
||||||
{
|
|
||||||
Date = startDate.AddDays(index),
|
|
||||||
TemperatureC = Random.Shared.Next(-20, 55),
|
|
||||||
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
|
|
||||||
}).ToArray());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
11
PowerShellBlazor/Models/Message.cs
Normal file
11
PowerShellBlazor/Models/Message.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
namespace PowerShellBlazor.Models
|
||||||
|
{
|
||||||
|
public enum PSStream { Output, Information, Progress, Warning, Error }
|
||||||
|
|
||||||
|
public class Message
|
||||||
|
{
|
||||||
|
public PSStream PSStream;
|
||||||
|
public string Data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
@page "/"
|
@page "/"
|
||||||
@inject IPowerShellService PowerShellService
|
@inject IPowerShellService PowerShellService
|
||||||
@inject IWebHostEnvironment WebHostEnvironment
|
|
||||||
@using System.Management.Automation;
|
|
||||||
<EditForm EditContext="@editContext" OnSubmit="RunScript">
|
<EditForm EditContext="@editContext" OnSubmit="RunScript">
|
||||||
<DataAnnotationsValidator />
|
<DataAnnotationsValidator />
|
||||||
<div class="mb-3">
|
<div class="mb-3">
|
||||||
@@ -16,9 +15,11 @@
|
|||||||
</EditForm>
|
</EditForm>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@foreach (MarkupString line in PowerShellService.Output)
|
@foreach (var message in PowerShellService.Output)
|
||||||
{
|
{
|
||||||
@line;
|
<div class="@message.PSStream">
|
||||||
|
@((MarkupString)message.Data)
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
@code
|
@code
|
||||||
@@ -33,14 +34,11 @@
|
|||||||
protected void RunScript()
|
protected void RunScript()
|
||||||
{
|
{
|
||||||
PowerShellService.Output = new();
|
PowerShellService.Output = new();
|
||||||
string pscommand = Path.Combine(WebHostEnvironment.ContentRootPath, "Scripts/" + script);
|
|
||||||
PowerShell shell = PowerShell.Create();
|
|
||||||
shell.AddCommand(pscommand);
|
|
||||||
PowerShellService.OutputChanged += OutputChanged;
|
PowerShellService.OutputChanged += OutputChanged;
|
||||||
Task.Run(() => PowerShellService.RunScript(shell, true));
|
Task.Run(() => PowerShellService.RunScript(script));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OutputChanged(object sender, List<string> newOutput)
|
private void OutputChanged(object sender, List<Message> newOutput)
|
||||||
{
|
{
|
||||||
InvokeAsync(() => this.StateHasChanged());
|
InvokeAsync(() => this.StateHasChanged());
|
||||||
}
|
}
|
||||||
|
|||||||
27
PowerShellBlazor/Pages/Index.razor.css
Normal file
27
PowerShellBlazor/Pages/Index.razor.css
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
.Output {
|
||||||
|
color: black
|
||||||
|
}
|
||||||
|
|
||||||
|
.Progress {
|
||||||
|
color: green
|
||||||
|
}
|
||||||
|
|
||||||
|
.Information {
|
||||||
|
color: blue
|
||||||
|
}
|
||||||
|
|
||||||
|
.Warning::before {
|
||||||
|
content: "*** Warning ***: "
|
||||||
|
}
|
||||||
|
|
||||||
|
.Warning {
|
||||||
|
color: orange
|
||||||
|
}
|
||||||
|
|
||||||
|
.Error::before {
|
||||||
|
content: "*** Error ***: "
|
||||||
|
}
|
||||||
|
|
||||||
|
.Error {
|
||||||
|
color: red
|
||||||
|
}
|
||||||
@@ -9,9 +9,11 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Microsoft.PowerShell.SDK" />
|
<None Remove="Microsoft.PowerShell.SDK" />
|
||||||
<None Remove="Scripts\" />
|
<None Remove="Scripts\" />
|
||||||
|
<None Remove="Models\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Scripts\" />
|
<Folder Include="Scripts\" />
|
||||||
|
<Folder Include="Models\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.6" />
|
<PackageReference Include="Microsoft.PowerShell.SDK" Version="7.2.6" />
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Components;
|
global using PowerShellBlazor.Models;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
using Microsoft.AspNetCore.Components.Web;
|
using Microsoft.AspNetCore.Components.Web;
|
||||||
using PowerShellBlazor.Data;
|
|
||||||
using PowerShellBlazor.Services;
|
using PowerShellBlazor.Services;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
for ($i=1; $i -le 5; $i++) {
|
for ($i=1; $i -le 5; $i++) {
|
||||||
Write-Progress "Loop $i - progress output (Write-Progress)"
|
Write-Progress "Loop $i - progress output (Write-Progress)"
|
||||||
|
Write-Information "Here's some information (Write-Information)"
|
||||||
Write-Output "Normal output text (Write-Output)"
|
Write-Output "Normal output text (Write-Output)"
|
||||||
Write-Warning "Here's some warning text (Write-Warning)"
|
Write-Warning "Here's some warning text (Write-Warning)"
|
||||||
Write-Error "Oh no, here's some error text (Write-Error)"
|
Write-Error "Oh no, here's some error text (Write-Error)"
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ namespace PowerShellBlazor.Services
|
|||||||
{
|
{
|
||||||
public interface IPowerShellService
|
public interface IPowerShellService
|
||||||
{
|
{
|
||||||
public List<string> Output { get; set; }
|
public List<Message> Output { get; set; }
|
||||||
public Task RunScript(PowerShell shell, bool varwidth);
|
public Task RunScript(string script);
|
||||||
|
|
||||||
event EventHandler<List<string>> OutputChanged;
|
event EventHandler<List<Message>> OutputChanged;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,126 +1,88 @@
|
|||||||
using System;
|
using System.Management.Automation;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Management.Automation;
|
|
||||||
|
|
||||||
namespace PowerShellBlazor.Services
|
namespace PowerShellBlazor.Services
|
||||||
{
|
{
|
||||||
public class PowerShellService : IPowerShellService
|
public class PowerShellService : IPowerShellService
|
||||||
{
|
{
|
||||||
public List<string> Output { get; set; } = new();
|
private IWebHostEnvironment _WebHostEnvironment;
|
||||||
|
|
||||||
private void AddOutput(string str)
|
public PowerShellService(IWebHostEnvironment webHostEnvironment)
|
||||||
{
|
{
|
||||||
Output.Add(str);
|
_WebHostEnvironment = webHostEnvironment;
|
||||||
OutputChanged.Invoke(this, Output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public event EventHandler<List<string>> OutputChanged;
|
public List<Message> Output { get; set; } = new();
|
||||||
|
|
||||||
public async Task RunScript(PowerShell shell, bool varwidth)
|
private Message prevMsg = new();
|
||||||
|
|
||||||
|
private void AddOutput(PSStream stream, string message)
|
||||||
{
|
{
|
||||||
if (shell == null)
|
Message msg = new()
|
||||||
{
|
{
|
||||||
AddOutput("Shell empty - nothing to execute");
|
PSStream = stream,
|
||||||
|
Data = message
|
||||||
|
};
|
||||||
|
|
||||||
|
if (msg == prevMsg)
|
||||||
|
{
|
||||||
|
Output.Last().Data += ".";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string fontstr = "";
|
Output.Add(msg);
|
||||||
if (varwidth != true)
|
prevMsg = msg;
|
||||||
{
|
}
|
||||||
fontstr = "face='monospace' size=3";
|
OutputChanged.Invoke(this, Output);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddOutput("<b>Executing: </b>" + shell.Commands.Commands[0].ToString());
|
public event EventHandler<List<Message>> OutputChanged;
|
||||||
|
|
||||||
|
public async Task RunScript(string script)
|
||||||
|
{
|
||||||
|
string pscommand = Path.Combine(_WebHostEnvironment.ContentRootPath, "Scripts/" + script);
|
||||||
|
if (!File.Exists(pscommand))
|
||||||
|
{
|
||||||
|
AddOutput(PSStream.Error, "File not found: " + pscommand);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PowerShell shell = PowerShell.Create();
|
||||||
|
shell.AddCommand(pscommand);
|
||||||
|
|
||||||
|
string fontstr = "";
|
||||||
|
|
||||||
|
AddOutput(PSStream.Output, "<b>Executing: </b>" + shell.Commands.Commands[0].ToString());
|
||||||
string prevmsg = "";
|
string prevmsg = "";
|
||||||
string msg = "";
|
string msg = "";
|
||||||
|
|
||||||
AddOutput("<br><b>BEGIN</b>");
|
AddOutput(PSStream.Output, "<b>BEGIN</b>");
|
||||||
AddOutput("<br>_________________________________________________________________________");
|
AddOutput(PSStream.Output, "_________________________________________________________________________");
|
||||||
|
|
||||||
var psOutput = new PSDataCollection<PSObject>();
|
var psOutput = new PSDataCollection<PSObject>();
|
||||||
|
|
||||||
// Collect powershell OUTPUT
|
|
||||||
psOutput.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
psOutput.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
||||||
{
|
{
|
||||||
msg = psOutput[e.Index].ToString();
|
AddOutput(PSStream.Output, psOutput[e.Index].ToString());
|
||||||
|
};
|
||||||
if (msg != prevmsg)
|
|
||||||
{
|
shell.Streams.Information.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
||||||
AddOutput("<br><span><font color=black " + fontstr + ">" + msg + "</font></span>");
|
{
|
||||||
}
|
AddOutput(PSStream.Information, shell.Streams.Information[e.Index].ToString());
|
||||||
else
|
|
||||||
{
|
|
||||||
AddOutput(".");
|
|
||||||
}
|
|
||||||
prevmsg = msg;
|
|
||||||
if (sender is not null)
|
|
||||||
{
|
|
||||||
var psoutput = (PSDataCollection<PSObject>)sender;
|
|
||||||
Collection<PSObject> results = psoutput.ReadAll();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
prevmsg = "";
|
|
||||||
// Collect powershell PROGRESS output
|
|
||||||
shell.Streams.Progress.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
shell.Streams.Progress.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
||||||
{
|
{
|
||||||
msg = shell.Streams.Progress[e.Index].Activity.ToString();
|
AddOutput(PSStream.Progress, shell.Streams.Progress[e.Index].Activity.ToString());
|
||||||
if (msg != prevmsg)
|
|
||||||
{
|
|
||||||
AddOutput("<br><span><font color=green " + fontstr + ">" + msg + "</font></span>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddOutput(".");
|
|
||||||
}
|
|
||||||
prevmsg = msg;
|
|
||||||
if (sender is not null)
|
|
||||||
{
|
|
||||||
var psprogress = (PSDataCollection<ProgressRecord>)sender;
|
|
||||||
Collection<ProgressRecord> results = psprogress.ReadAll();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
prevmsg = "";
|
|
||||||
// Collect powershell WARNING output
|
|
||||||
shell.Streams.Warning.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
shell.Streams.Warning.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
||||||
{
|
{
|
||||||
msg = shell.Streams.Warning[e.Index].ToString();
|
AddOutput(PSStream.Warning, shell.Streams.Warning[e.Index].ToString());
|
||||||
if (msg != prevmsg)
|
|
||||||
{
|
|
||||||
AddOutput("<br><span><font color=orange " + fontstr + "><b>***WARNING***:</b> " + msg + "</font></span>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddOutput(".");
|
|
||||||
}
|
|
||||||
prevmsg = msg;
|
|
||||||
if (sender is not null)
|
|
||||||
{
|
|
||||||
var pswarning = (PSDataCollection<WarningRecord>)sender;
|
|
||||||
Collection<WarningRecord> results = pswarning.ReadAll();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
prevmsg = "";
|
|
||||||
// Collect powershell ERROR output
|
|
||||||
shell.Streams.Error.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
shell.Streams.Error.DataAdded += delegate (object? sender, DataAddedEventArgs e)
|
||||||
{
|
{
|
||||||
msg = shell.Streams.Error[e.Index].ToString();
|
AddOutput(PSStream.Error, shell.Streams.Error[e.Index].ToString());
|
||||||
if (msg != prevmsg)
|
|
||||||
{
|
|
||||||
AddOutput("<br><span><font color=red " + fontstr + "><b>***ERROR***:</b> " + msg + "</font></span>");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
AddOutput(".");
|
|
||||||
}
|
|
||||||
prevmsg = msg;
|
|
||||||
if (sender is not null)
|
|
||||||
{
|
|
||||||
var pserror = (PSDataCollection<ErrorRecord>)sender;
|
|
||||||
Collection<ErrorRecord> results = pserror.ReadAll();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute powershell command
|
// Execute powershell command
|
||||||
@@ -129,9 +91,8 @@ namespace PowerShellBlazor.Services
|
|||||||
// Wait for powershell command to finish
|
// Wait for powershell command to finish
|
||||||
IasyncResult.AsyncWaitHandle.WaitOne();
|
IasyncResult.AsyncWaitHandle.WaitOne();
|
||||||
|
|
||||||
|
AddOutput(PSStream.Output, "_________________________________________________________________________");
|
||||||
AddOutput("<br>_________________________________________________________________________");
|
AddOutput(PSStream.Output, "<b>EXECUTION COMPLETE</b>");
|
||||||
AddOutput("<br><b>EXECUTION COMPLETE</b>");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
@inherits LayoutComponentBase
|
@inherits LayoutComponentBase
|
||||||
|
|
||||||
<PageTitle>PowerShellBlazor</PageTitle>
|
<PageTitle>PowerShell Blazor</PageTitle>
|
||||||
|
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<div class="sidebar">
|
<div class="sidebar">
|
||||||
|
|||||||
@@ -1,22 +1,12 @@
|
|||||||
<div class="top-row ps-3 navbar navbar-dark">
|
<div class="top-row ps-3 navbar navbar-dark">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<a class="navbar-brand" href="">PowerShellBlazor</a>
|
<a class="navbar-brand" href="">PowerShell Blazor</a>
|
||||||
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
<button title="Navigation menu" class="navbar-toggler" @onclick="ToggleNavMenu">
|
||||||
<span class="navbar-toggler-icon"></span>
|
<span class="navbar-toggler-icon"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
|
|
||||||
<nav class="flex-column">
|
|
||||||
<div class="nav-item px-3">
|
|
||||||
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
|
|
||||||
<span class="oi oi-home" aria-hidden="true"></span> Home
|
|
||||||
</NavLink>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
@code {
|
@code {
|
||||||
private bool collapseNavMenu = true;
|
private bool collapseNavMenu = true;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user