はじめに
PowerShellは強力なスクリプト言語であり、システム管理や自動化に広く使用されています。しかし、C#のような他のプログラミング言語の機能を活用することで、さらに強力なスクリプトを作成することができそう。ここでは、PowerShellでC#のLINQ(Language Integrated Query)で使用する方法について調査しました。
LINQとは?
LINQは、C#や他の.NET言語で使用されるデータクエリ言語です。リストや配列などのコレクションに対して、簡潔で読みやすいクエリを記述することができます。
PowerShellでC#コードを実行する方法
PowerShellでは、Add-Type
コマンドレットを使用してC#コードを実行することができます。以下のサンプルコードでは、名前リストをフィルタリングするC#のメソッドをPowerShellから呼び出しています。
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
try { # デバッグメッセージ Write-Output "C#コードをテキストファイルに出力中..." # デスクトップフォルダのパスを取得 $desktopPath = [Environment]::GetFolderPath([System.Environment+SpecialFolder]::Desktop) $csFilePath = Join-Path -Path $desktopPath -ChildPath "LinqSample.cs" # C#コードをテキストファイルに出力(UTF-8エンコーディングを指定) $csCode = @" using System; using System.Collections.Generic; using System.Linq; public class LinqSample { // 名前リストをフィルタリングするメソッド // names: フィルタリング対象の名前リスト // filter: フィルタ文字列 public static List<string> FilterNames(List<string> names, string filter) { // LINQを使用してフィルタ文字列で始まる名前を抽出 return names.Where(name => name.StartsWith(filter)).ToList(); } } "@ Set-Content -Path $csFilePath -Value $csCode -Encoding UTF8 Write-Output "C#コードをテキストファイルに出力完了: $csFilePath" # 型が既に登録済みか確認 $typeName = "LinqSample" $typeExists = [AppDomain]::CurrentDomain.GetAssemblies() | ForEach-Object { $_.GetTypes() } | Where-Object { $_.FullName -eq $typeName } if ($typeExists) { # 型が既に登録されている場合のメッセージ Write-Output "型 '$typeName' は既に登録されています。Add-Type をスキップします。" Write-Output "理由: PowerShellでは、一度Add-Typeで追加された型は、同じセッション内で再度追加できません。" Write-Output "対応策: 型を再定義するには、セッションを再起動する必要があります。" Write-Output "この判定を入れている理由: PowerShell ISEなどのデバッグ実行環境で、同一セッション内でスクリプトをリランする際にエラーを防ぐためです。" } else { # C#コードをPowerShellに追加して実行(UTF-8エンコーディングを指定) Write-Output "C#コードをPowerShellに追加中..." $csCode = Get-Content -Path $csFilePath -Raw -Encoding UTF8 Add-Type -TypeDefinition $csCode -Language CSharp Write-Output "C#コードをPowerShellに追加完了" } # サンプルデータ $names = @("John", "Jane", "Mike", "Sara", "James") Write-Output "サンプルデータ: $($names -join ', ')" # フィルタ文字 $filter = "J" Write-Output "フィルタ文字: $filter" # C#のメソッドを呼び出してフィルタリング Write-Output "C#のメソッドを呼び出してフィルタリング中..." $filteredNames = [LinqSample]::FilterNames($names, $filter) Write-Output "フィルタリング完了: $($filteredNames -join ', ')" # 件数を確認 Write-Output "フィルタリングされた名前の件数: $($filteredNames.Count)" # フィルタリングされた名前を1つずつ出力 Write-Output "フィルタリングされた名前を1つずつ出力:" foreach ($name in $filteredNames) { Write-Output $name } } catch { Write-Output "エラーが発生しました: $_" } |
再読み込み時の注意点
PowerShellでは、一度Add-Type
で追加された型は、同じセッション内で再度追加することができません。そのため、スクリプトを再実行する際には、セッションを再起動する必要があります。これにより、型の再定義が可能になります。
まとめ
C#とのハイブリッドな処理はデバッグも大変で、実務で使えるかどうかはなんともですが、PowerShellでC#のLINQを活用することで、より強力なデータ操作が可能にはなります。
コメント