DEV Community

Masui Masanori
Masui Masanori

Posted on

12

Execute PowerShell scripts in C#

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();
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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 }

Enter fullscreen mode Exit fullscreen mode

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();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

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();
        }
    }
Enter fullscreen mode Exit fullscreen mode

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.
...
Enter fullscreen mode Exit fullscreen mode

So I think I should use "AddScript".

Resources

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more