Intro
This time, I will try executing PowerShell scripts in C#.
There are some way to do this.
For example, I can use Process class.
PsAccessor.cs
using System.Diagnostics;
namespace AccessPowerShellSample;
public class PsAccessor
{
public async Task<string?> ExecuteProcess()
{
using(var app = new Process())
{
app.StartInfo.FileName = "powershell.exe";
app.StartInfo.Arguments = "echo HelloWorld!!";
app.EnableRaisingEvents = true;
app.StartInfo.RedirectStandardOutput = true;
app.StartInfo.RedirectStandardError = true;
// Must not set true to execute PowerShell command
app.StartInfo.UseShellExecute = false;
app.Start();
using(var o = app.StandardOutput)
{
return await o.ReadToEndAsync();
}
}
}
}
I also can "PowerShell" class.
So I will try it in this time.
Use PowerShell class.
To use "PowerShell", I have to add some NuGet packages.
- System.Management.Automation
- Microsoft.PowerShell.Commands.Diagnostics
- Microsoft.PowerShell.ConsoleHost
- Microsoft.PowerShell.Commands.Utility
- Microsoft.PowerShell.Commands.Management
- Microsoft.WSMan.Management
PsAccessor.cs
using System.Management.Automation;
namespace AccessPowerShellSample;
public class PsAccessor
{
public string? GenerateHmacSha512(string inputData, string key)
{
using(var ps = PowerShell.Create())
{
ps.AddCommand("echo");
ps.AddArgument("Hello World!");
var results = ps.Invoke<string>();
return results.FirstOrDefault();
}
}
}
AddScript
How about more complicated case?
For example, I will try generating a hash value by HMAC SHA-512.
hashValueGenerator.ps1
param(
[Parameter()]
[String] $secret_key,
[String] $message
)
$oHMACSHA512 = New-Object System.Security.Cryptography.HMACSHA512
$oHMACSHA512.key = [Text.Encoding]::ASCII.GetBytes($secret_key)
$signature_rawout = $oHMACSHA512.ComputeHash([Text.Encoding]::ASCII.GetBytes($message))
$signature = ""
$signature_rawout | ForEach-Object { $i = [Convert]::ToString($_,16); if ($i.length -eq 1) { $i ='0' + $i }; $signature += $i }
To execute it, I can use "Process" like below.
public async Task<string?> ExecuteProcess(string key, string message)
{
using(var app = new Process())
{
app.StartInfo.FileName = "powershell.exe";
app.StartInfo.Arguments = $"$oHMACSHA512 = New-Object System.Security.Cryptography.HMACSHA512;$oHMACSHA512.key = [Text.Encoding]::ASCII.GetBytes('{key}');$signature_rawout = $oHMACSHA512.ComputeHash([Text.Encoding]::ASCII.GetBytes('{message}'));$signature = '';$signature_rawout | ForEach-Object {{ $i = [Convert]::ToString($_,16); if ($i.length -eq 1) {{ $i ='0' + $i }}; $signature += $i }};[Convert]::ToBase64String($signature_rawout)";
app.EnableRaisingEvents = true;
app.StartInfo.RedirectStandardOutput = true;
app.StartInfo.RedirectStandardError = true;
// Must not set true to execute PowerShell command
app.StartInfo.UseShellExecute = false;
app.Start();
using(var o = app.StandardOutput)
{
return await o.ReadToEndAsync();
}
}
}
Although I can get result, but it's very hard to debug.
I also can use PowerShell script files.
public string? GenerateHmacSha512(string key, string message)
{
using(var ps = PowerShell.Create())
{
ps.AddScript(File.ReadAllText("./hashValueGenerator.ps1"));
ps.AddParameter("secret_key", key);
ps.AddParameter("message", message);
var results = ps.Invoke<string>();
return results.FirstOrDefault();
}
}
I can use "AddCommand" to do this.
But I will get error because PowerShell execution policy.
Unhandled exception. System.Management.Automation.PSSecurityException: File C:\Users\example\OneDrive\Documents\workspace\AccessPowerShellSample\hashValueGenerator.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.
...
So I think I should use "AddScript".
Top comments (0)