この前C#でPowershellを動かせたので、ASP.NET Core Web APIでPowershellを動かしてみたという記事です
ASP.NETやC#関連の記事はカテゴリにまとめておりますのでご覧ください
実際に作ってみよう
事前準備
Visual Studioを起動して新規プロジェクトの作成画面から、ASP.NET Core Web APIを選択します
ここはお好みで
ここでは.NET6.0にしていますが、7.0を推奨します(後述のnugetパッケージのバージョンに注意)
動作テストとnugetパッケージの追加
初期画面ですね、早速上にある再生ボタンみたいなボタンを押してみます。
実行されてAPIのテストができるSwaggerが開きました。動作確認したのでブラウザを閉じるかVisual Studioから停止させます。
次にパッケージを導入していきます。
依存関係のところでNuGetパッケージの管理を押します
たぶんOffline Packageが導入されているかと思うので右の歯車をクリックしてパッケージソースをオンラインから取ってこれるようにします。
(デフォルトでnuget.orgが入っていればここは飛ばして大丈夫です。)
パッケージソースを新規追加し、
powershellと検索してMicrosoft.Powershell.SDKを見つけて入れます。
ここで重要なポイントです。
.Net 6.0にした場合は基本バージョン6.2.7を入れます。
7.x.xを入れる場合は.Net 7.0のプロジェクトにしてください。
(画像は後付けなので7.3.2が入ってます)
APIコントローラーの作成とコード作成
ソリューションエクスプローラーのControllerの部分で右クリックし、追加→新しい項目の作成をクリックします。
次にpowershellを実行するコントローラーを作成します。APIコントローラー(空)を選択しました。
特に指定がなければValuesControllerという名前で作成されます。
こんな感じが初期画面ですが、全部消して以下をコピペします
using Microsoft.AspNetCore.Mvc; using System.Management.Automation; using System.Management.Automation.Runspaces; namespace test.Controllers //ここはプロジェクト名.controllerです { [Route("api/[controller]")] [ApiController] public class ValuesController : ControllerBase { //GET hostnameを取得 [HttpGet] [Route("gethost")] public void RunPowerShell() { using (PowerShell ps = PowerShell.Create()) { var script = @" $res = invoke-command -scriptblock {hostname} | out-file C:\log\hostname.txt "; ps.AddScript(script); //PowerShellコマンドを実行 ps.Invoke(); } } } }
今回のAPIでは前の記事と違ってRunspaceを使わない簡単なpowershellの実行方法にしています。
中身はコンピューター名をC:\log\hostname.txtに入れるという動作になっています。
そのため、事前にC直下にlogファイルを作成してください。
(変数に入れたりinvoke-commandを使ったり無駄な部分がありますが検証で試した跡なので気にしないでください)
ちゃんとpowershellのパッケージを入れておけば動作すると思います
動作確認
それでは実行してみましょう。
こんな感じにちゃんと表示されると思います。
Get⇒try it out ⇒executeの順に押していくとAPIが動きます
200が帰ってきたことが確認できました
ちゃんと出力も出来てました
もちろんswaggerに書いてあるRequest URLを直接ブラウザに入力しても動きます。完璧なAPIです。
まとめ
このような感じで簡単にpowershellを実行できるAPIを作ることが出来ました。
活用方法としてはAPI用のサーバーの中にpowershellで運用に必要な機能を作ったモジュールを作成しておき、APIからinvoke-commandでAPI用サーバーへコマンドを投げることによって、
APIを駆使したWindows Server環境が作成できます。(不特定多数のユーザーが個別でVMを作ったり、消したり、メモリを変えたりなど)
ただこの前実行したrunspaceとの違いがよくわかっていないのでもうちょっと調べたいですね。。。
ただ.NET 6ではもうrunspaceinvokeが使えないっぽいです。。?これが後継ってことでいいのかな。。