c#でPowerShellスクリプトを実行する方法

c# でPowerShellスクリプトを実行する方法を紹介します。

この記事での実行方法は、System.Management.Automationを使用する方法ではなく、Powershell.exe を呼び出して実行します。

実行するソースコード


//using System.Diagnostics;


/// <summary>
/// PowerShellスクリプトを実行する
/// </summary>
/// <param name="ps1FilePath">PowerShellスクリプト(*.ps1)ファイル名</param>
/// <param name="args">引数リスト</param>
/// <param name="stdOut">標準出力</param>
/// <param name="stdErr">標準エラー出力</param>
/// <param name="exitCode">終了コード</param>
public static void ExecPSProcess(string ps1FilePath, List<PowerShellArgs> args, out string stdOut, out string stdErr, out int exitCode)
{
    stdOut = "";
    stdErr = "";
    exitCode = 0;

    try
    {
        string cmdStr = "";
        cmdStr = $"-File {ps1FilePath} ";
        foreach(var item in args)
        {
            cmdStr = cmdStr + $"-{item.argName} {item.argValue}";
        }

        System.Diagnostics.Process process = new System.Diagnostics.Process();
        ProcessStartInfo processStartInfo = new ProcessStartInfo("powershell.exe", cmdStr);

        processStartInfo.CreateNoWindow = true;
        processStartInfo.UseShellExecute = false;

        processStartInfo.RedirectStandardOutput = true;
        processStartInfo.RedirectStandardError = true;

        process = System.Diagnostics.Process.Start(processStartInfo);
        process.WaitForExit();

        stdOut = process.StandardOutput.ReadToEnd();
        stdErr = process.StandardError.ReadToEnd();
        exitCode = process.ExitCode;

        process.Close();

    }
    catch
    {
        throw;
    }
}

以下のコードで、PowerShell.exe の後に続くコマンド文字列を作成します。 -FileスイッチでPowerShellスクリプトファイルパスを指定しています。 スクリプトの引数が格納されているargsforeachでループして、引数を指定するコマンド文字列を作成します。 PowerShellArgsクラスは後述しています。

    string cmdStr = "";
    cmdStr = $"-File {ps1FilePath} ";
    foreach(var item in args)
    {
        cmdStr = cmdStr + $"-{item.argName} {item.argValue}";
    }

プロセスオブジェクトを作成して、コマンド文字列を指定します。

    System.Diagnostics.Process process = new System.Diagnostics.Process();
    ProcessStartInfo processStartInfo = new ProcessStartInfo("powershell.exe", cmdStr);

ウィンドウの非表示などを指定します。 プロセスを開始し、標準出力、標準エラー出力、終了コードを取得します。

    processStartInfo.CreateNoWindow = true;
    processStartInfo.UseShellExecute = false;

    processStartInfo.RedirectStandardOutput = true;
    processStartInfo.RedirectStandardError = true;

    process = System.Diagnostics.Process.Start(processStartInfo);
    process.WaitForExit();

    stdOut = process.StandardOutput.ReadToEnd();
    stdErr = process.StandardError.ReadToEnd();
    exitCode = process.ExitCode;

    process.Close();

引数を指定するクラスPowerShellArgsクラス

PowerShellスクリプトに渡す引数は以下のクラスを用いて説明します。 上記で説明した関数では、複数指定されることを考慮し、リスト型にして渡しています。

    /// <summary>
    /// PowerShellスクリプト呼び出し引数クラス
    /// </summary>
    public class PowerShellArgs
    {
        /// <summary>
        /// 引数名称
        /// </summary>
        /// <value></value>
        public string argName {get; set;}

        /// <summary>
        /// 値
        /// </summary>
        /// <value></value>
        public string argValue {get; set;}
    }

実行方法

例えば、以下のようなPowerShellスクリプトを実行するとします。 引数OpenFileNameで指定したファイルを、Visual Studio Codeで開くという動作をします。

Param($OpenFileName)

code $OpenFileName

これを実行するためのExecPSProcess関数を呼び出すコードは以下になります。

string ps1FilePath = @"D:\OpenFileWithCode.ps1";
PowerShellArgs args = new PowerShellArgs();
args.argName = "OpenFileName";
args.argValue = @"D:\docs.md";

List<PowerShellArgs> argsList  = new List<PowerShellArgs>();
argsList.Add(args);

string stdout = "";
string stderr = "";
int exitCode = 0;

ExecPSProcess(ps1FilePath, argsList, out stdout, out stderr, out exitCode);

Console.WriteLine(exitCode);
Console.WriteLine(stdout);
Console.WriteLine(stderr);

実行するPowerShellスクリプトファイルパスを指定し、引数を定義します。 引数はリスト型のPowerShellArgsオブジェクトに格納します。

string ps1FilePath = @"D:\OpenFileWithCode.ps1";
PowerShellArgs args = new PowerShellArgs();
args.argName = "OpenFileName";
args.argValue = @"D:\docs.md";

List<PowerShellArgs> argsList  = new List<PowerShellArgs>();
argsList.Add(args);

標準出力、標準エラー出力、終了コードを取得する変数を定義し、ExecPSProcessを呼び出します。

string stdout = "";
string stderr = "";
int exitCode = 0;

ExecPSProcess(ps1FilePath, argsList, out stdout, out stderr, out exitCode);

Console.WriteLine(exitCode);
Console.WriteLine(stdout);
Console.WriteLine(stderr);

速攻でメモできる QuickNote リリースしました!

QuickNoteは動作が超軽量でサクサクかけるノートアプリです。一瞬の閃きを逃さずにノートを開き書き始めることができます。 アカウント登録も不要です。お試しあれ!

Excel操作をコマンドで! proBoarderExcel

Excelはマウスで操作するのが基本ですが、マウス操作に疲れてはいませんか? キーボードでExcel操作ができるようになるアプリです。オープンソースで無料です。

積み上げ! Daily Stack リリースしました!

Daily Stack は日々の積み上げを管理するToDoアプリです。過去の積み上げの振り返りだけでなく、ツイート機能もあります。 アカウント登録不要ですぐに使い始めることができます。

ExecNote.app リリースしました!

ExecNoteは、コードが実行できるMarkdownアプリケーションです。Markdownドキュメント内に記載したコードをクリックすると実行ができます。わざわざターミナルを 起動させる必要がありません!無料ですのでもしよければダウンロードをお願いします。

About Me

11年目のシステムエンジニアです。アプリで生活や仕事を改善したい🐱仕事効率化、自動化のアプリ開発が得意です、ご相談ください。 🚀エンタメ系アプリの開発も模索中🐬社内SEや個人アプリ開発者、システムエンジニアになりたい人と繋がりたい🐱