\

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

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

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

実行するソースコード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

//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クラスは後述しています。

1
2
3
4
5
6
string cmdStr = "";
cmdStr = $"-File {ps1FilePath} ";
foreach(var item in args)
{
cmdStr = cmdStr + $"-{item.argName} {item.argValue}";
}

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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スクリプトに渡す引数は以下のクラスを用いて説明します。
上記で説明した関数では、複数指定されることを考慮し、リスト型にして渡しています。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/// <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で開くという動作をします。

1
2
3
Param($OpenFileName)

code $OpenFileName

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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オブジェクトに格納します。

1
2
3
4
5
6
7
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を呼び出します。

1
2
3
4
5
6
7
8
9
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);

About Me

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