PowerShellにおけるSystem.DirectoryServices.ResultPropertyCollectionの理解

PowerShellを使用してActive Directoryをクエリしているとき、System.DirectoryServices.ResultPropertyCollectionからプロパティにアクセスしようとすると、困惑するような動作に遭遇することがあります。この投稿では、DirectorySearcherを通じて情報を取得する際に発生する一般的な問題、つまり2つの異なる出力が予期しない結果をもたらす理由を解明します。問題、その根本原因、そしてそれを効果的に解決する方法を探ってみましょう。

問題

PowerShellスクリプトを設定し、DirectorySearcherクラスを使用してActive Directory内のコンピュータオブジェクトを検索していますが、出力に不一致が見られます。以下は、あなたのコードを簡略化したものです:

$objSearcher = New-Object System.DirectoryServices.DirectorySearcher  
$objSearcher.SearchRoot = New-Object System.DirectoryServices.DirectoryEntry  
$objSearcher.Filter = ("(objectclass=computer)")  
$computers = $objSearcher.findall()  

コンピュータの名前を印刷しようとすると、次の2つの出力が観察されます:

$computers | %{
    "サーバー名(引用符付き) $_.properties.name" 
    "サーバー名(引用符なし) " + $_.properties.name 
}

そして次に:

$computers[0] | %{"$_.properties.name"; $_.properties.name}

結果として、引用符を使用した場合はプロパティの型名(System.DirectoryServices.SearchResult.properties.name)が表示されますが、引用符なしの場合は値が表示されます。このニュアンスを理解することが、PowerShellにおけるプロパティ取得をマスターするための鍵です。

なぜ出力が異なるのか?

この不一致は、PowerShellが文字列内の変数やプロパティをどのように評価するかから生じます。$_を文字列に含めると、PowerShellはそれを全体のオブジェクトとして扱います:

  • 引用符のあるコンテキスト";"を使用する文字列、例えば "サーバー名(引用符付き) $_.properties.name" の場合、PowerShellはプロパティを評価せず、オブジェクトのToStringメソッドを参照します。この場合、これはプロパティの型名にデフォルト設定されます。

  • 引用符のないコンテキスト:逆に、 "サーバー名(引用符なし) " + $_.properties.nameのように引用符なしで使用すると、PowerShellは最初にプロパティを評価し、その後に文字列に連結します。したがって、型名ではなく、プロパティに格納された実際の値が取得されます。

出力を修正する

引用符付きの文字列内で意図したプロパティ値を取得するには、サブエクスプレッション構文を使用して明示的に評価を呼び出すことができます:

"サーバー名(引用符付き) $($_.properties.name)"  

この$()の使用は、PowerShellに対して、文字列の残りの部分を実行する前にその内部を評価するよう指示し、期待される正しい出力をもたらします。

結果プロパティコレクションの探求

ResultPropertyCollectionを作業する際は、プロパティのコレクションを扱っていることを忘れないでください。PowerShellコマンドラインからオブジェクトモデルを直接調べることができます。例えば、$computers[0].propertiesGet-Memberにパイプすることで、利用可能なメンバーやプロパティに関する情報を確認できます:

$computers[0].properties | Get-Member

ここでは、プロパティの値を取得するValuesプロパティを見ることができます。この探求は、プロパティをより効果的にナビゲートする理解を深めます。

結論

PowerShellおよびActive DirectoryのSystem.DirectoryServicesを扱う際には、文字列評価がオブジェクトとそのプロパティにどのように作用するかを理解することが重要です。これらのプロパティがアクセスされる異なるコンテキストを認識することで、混乱を避け、期待する形式で情報を取得できます。

ResultPropertyCollectionのような複雑なPowerShell構造をナビゲートするのは最初は困難に思えるかもしれませんが、練習とより深い理解を通じて、スクリプト作成の旅の中でそれが自然になることに気づくでしょう。