PowerShellでLINQを活用する方法:C#コードの統合と実行

PowerAutomate

はじめに

PowerShellは強力なスクリプト言語であり、システム管理や自動化に広く使用されています。しかし、C#のような他のプログラミング言語の機能を活用することで、さらに強力なスクリプトを作成することができそう。ここでは、PowerShellでC#のLINQ(Language Integrated Query)で使用する方法について調査しました。

LINQとは?

LINQは、C#や他の.NET言語で使用されるデータクエリ言語です。リストや配列などのコレクションに対して、簡潔で読みやすいクエリを記述することができます。

PowerShellでC#コードを実行する方法

PowerShellでは、Add-Typeコマンドレットを使用してC#コードを実行することができます。以下のサンプルコードでは、名前リストをフィルタリングするC#のメソッドをPowerShellから呼び出しています。

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を活用することで、より強力なデータ操作が可能にはなります。

ライセンス:本記事のテキスト/コードは特記なき限り CC BY 4.0 です。引用の際は出典URL(本ページ)を明記してください。
利用ポリシー もご参照ください。

コメント

タイトルとURLをコピーしました