Execute PowerShell scripts in C#
Masui Masanori
Posted on February 12, 2023
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".
Resources
💖 💪 🙅 🚩
Masui Masanori
Posted on February 12, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
csharp Boosting Developer Productivity with .NET 9 SDK: Essential Tools and Features
November 30, 2024