3

次のような親子関係を持つオブジェクトがあるとします。

public class Node
{
   public string Name { get; set; }
   public string Type { get; set; }
   public Node Parent { get; set; }
}

ここで、次のような構文をサポートするコマンドレットを作成したいと思います。

Get-Node | where {$_.Type -eq "SomeType" -and $_.Parent.Name -eq "SomeName" }

ここで、Parent プロパティは、何らかの方法でパイプライン内の別のオブジェクトを参照する必要があります。このようなことは PowerShell でも可能ですか? そうでない場合、代替手段は何ですか?

[編集] 上記のクラスを次のように使用すると:

var root = new Node
{
    Name = "root",
    Type = "root",
    Parent = null
};
var nodeA = new Node
{
    Name = "A",
    Type = "node",
    Parent = root
}
WriteObject(root);
WriteObject(nodeA);

次に、モジュールをロードして、次のコマンドを試してください。

Get-MyNode | where {$_.Parent.Name = "root"}

次のエラーが表示されます。

Property 'Name' cannot be found on this object; make sure it exists and is settable.
At line:1 char:31
+ Get-MyNode | where {$_.Parent. <<<< Name = "root"}
    + CategoryInfo          : InvalidOperation: (Name:String) [], RuntimeException
    + FullyQualifiedErrorId : PropertyNotFound

Parent プロパティが、実際の Node オブジェクトのようにパイプライン内の別のオブジェクトを参照するようにしたいと考えています。

[編集] このエラーは、クラス定義にない public キーワードが原因でした。キーワードを追加すると問題が修正され、例が機能するようになりました。

4

1 に答える 1

2

Get-Node コマンドレットが完全に設定されたオブジェクト グラフを返すことを期待しています。XML を使用した同様の例を次に示します。

$xml = [xml]@'
<?xml version="1.0" encoding="ISO-8859-1"?>
 <bookstore>
     <book>
       <title lang="eng">Harry Potter</title>
       <price>29.99</price>
     </book>
     <book>
       <title lang="eng">Learning XML</title>
       <price>39.95</price>
     </book>
 </bookstore> 
'@

$xml.SelectNodes('//*') | Where {$_.ParentNode.Name -eq 'book'}

パイプライン内の別のオブジェクトへのアクセスに関する質問への回答として、後で参照できるパイプラインの一部として中間変数を作成することは珍しくありません。

Get-Process | Foreach {$processName = $_.Name; $_.Modules} | 
              Foreach {"$processName loaded $($_.ModuleName)"}

このシナリオでは、System.Diagnostics.Process オブジェクトの名前を隠してから、パイプラインでまったく異なる型、つまり System.Diagnostic.ProcessModule を伝播します。次に、隠しプロセス名とモジュール名を組み合わせて、必要な出力を生成できます。

上記のアプローチは教育目的には適していますが、実際には正規の PowerShell ではありません。これは、PowerShell でこれを行うより一般的な方法です。

Get-Process | Select Name -Exp Modules | Foreach {"$($_.Name) loaded $($_.ModuleName)"}

このシナリオでは、プロセスの名前を取得し、それを各 ProcessModule オブジェクトに射影しました。モジュール コレクションを列挙しようとすると、一部のプロセスでエラーが発生することに注意してください。

于 2012-08-04T16:44:39.537 に答える