web-dev-qa-db-ja.com

PowerShellで次のことが可能ですか: "Select-Object <Property>。<SubProperty>"?

シナリオ:Select-Objectを使用して、パイプされたオブジェクトのプロパティにアクセスしています。これらのプロパティの1つは、それ自体がオブジェクトです。それをPropertyObjectと呼びましょう。そのPropertyObjectのプロパティ(Property1など)にアクセスしたいと思います。次のように、Property1にアクセスするためのすてきでクリーンな方法はありますか?

...| select-object PropertyObject.Property1

実験中、次のようなことをした場合にのみ機能させることができます。

...| select-object {$_.PropertyObject.Property1}

適切な列名で表示したい場合は、さらに面倒になります。

...| select-object @{Name="Property1"; Expression={$_.PropertyObject.Property1}}

PowerShellが一般的にどれほどクリーンで簡潔であるかを考えると、何かが足りないので、プロパティのプロパティにアクセスするためのよりクリーンな方法があるはずだと思わずにはいられません。ある?

EDIT: Mattの要求に応じて、具体的な例を次に示します。

私はXMLファイルBooks3.xmlを読んでいます:

<?xml version="1.0"?>
<catalog>
   <book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date inprint="false">2000-10-01</publish_date>
      <description>An in-depth look at creating applications 
      with XML.</description>
      <publisher>
        <name>Simon and Schuster</name>
        <country>USA</country>
        <city>New York</city>
      </publisher>
   </book>
   <book id="bk102">
      <author>Ralls, Kim</author>
      <title>Midnight Rain</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date inprint="true">2000-12-16</publish_date>
      <description>A former architect battles corporate zombies, 
      an evil sorceress, and her own childhood to become queen 
      of the world.</description>
      <publisher>
        <name>HarperCollins</name>
        <country>USA</country>
        <city>New York</city>
      </publisher>
   </book>
   <book id="bk103">
      <author>Corets, Eva</author>
      <title>Maeve Ascendant</title>
      <genre>Fantasy</genre>
      <price>5.95</price>
      <publish_date inprint="false">2000-11-17</publish_date>
      <description>After the collapse of a nanotechnology 
      society in England, the young survivors lay the 
      foundation for a new society.</description>
      <publisher>
        <name>Macmillan</name>
        <country>United Kingdom</country>
        <city>London</city>
      </publisher>
   </book>
</catalog>

XMLをXmlDocumentにロードするコード:

$filePath = "C:\Temp\books3.xml"
$xmlDoc = new-object xml
$xmlDoc.load($filePath)

各本の詳細を読み込もうとしています:

$xmlDoc.catalog.book | select author, title, publisher.name

結果:

author                     title                      publisher.name
------                     -----                      --------------
Gambardella, Matthew       XML Developer's Guide
Ralls, Kim                 Midnight Rain
Corets, Eva                Maeve Ascendant
12
Simon Tewsi

私たちがテストするために実際に再現可能なものがあれば簡単ですが、Get-Itemsreturnでそれを偽造することができます。

(Get-Item C:\temp\logoutput).Parent.Name

.Parentは実際にはSystem.IO.DirectoryInfoオブジェクトです。 PowerShell 3.0ドット表記を使用して、nameparentを取得します

select呼び出しをチェーンすることによって同じ結果を取得できます

Get-Item C:\temp\logoutput | select -expand Parent | Select -Expand name

もちろん、これはPowerShell 2.0で機能しますが、簡潔で3.0バージョンではありません。

質問編集後

何を望んでいるのかわからない。あなたが持っているものは、あなたが持っている方法でサブプロパティを抽出するのに役立ちます。私はより直感的で親しみやすい代替アプローチしか提供できませんが、結果は同じです。

$xml.catalog.book | ForEach-Object{
    $_ | Add-Member NoteProperty "PublisherName" $_.publisher.name -PassThru}

もちろん、出力を必要なプロパティに制限するためにselectを使用する必要があるかもしれませんが、それは別のオプションです。

5
Matt

計算されたプロパティ を使用できます。短い形式でこれが可能になります。

$xmlDoc.catalog.book | select author, title, {$_.publisher.name}

プロパティ名が重要な場合は、に追加する必要があります。

$xmlDoc.catalog.book | select author, title, @{N="PublisherName";E={$_.publisher.name}}

ここで、Nは名前の略で、Eは表現の略です。

23
khaledh

私も、オブジェクトのサブプロパティの選択を実現する方法を探していました。私の場合は、DNSサーバーのゾーンデータをエクスポートするためでした。私が目標を達成するために使用したものの根性を共有し、ここにこの投稿が役立ちました!

あなたが探していたことを具体的に行うには、次のようにコードを変更してみてください。

$xmlDoc.catalog.book | Select Author, Title, -Expand Publisher | Select Author, Title, Name | Sort Author | FT -auto

あなたが提供したテーブル出力に基づいて、上記はうまくいくはずです。それはあなたが以下に見るであろう私のために働いた。

このスクリプトは、私が必要としているものに最適であり、さまざまなアイデアを組み合わせたものです。うまくいけば、それは他の誰かのために働く。

$Zones = @(Get-DnsServerZone)
ForEach ($Zone in $Zones) {
    Write-Host "`n$($Zone.ZoneName)" -ForegroundColor "Yellow"
    $Data = New-Object System.Object
    $Data = $Zone | Get-DnsServerResourceRecord
    $Data | Add-Member -MemberType NoteProperty -Name "ZoneName" -Value $Zone.ZoneName
    $Data += $Data
    $Data | Select-Object ZoneName, HostName, RecordType -Expand RecordData | Select ZoneName, HostName, RecordType, IPv4Address, HostNameAlias, NameServer, PrimaryServer, ExpireLimit, MinimumTimeToLive, RefreshInterval, ResponsiblePerson, RetryDelay, SerialNumber, DomainName, Port, Priority, Weight | Sort RecordType, HostName | Export-Csv -NoTypeInformation "$($Zone.ZoneName).csv"
}

黄色の前景は、エクスポートする前に出力を確認するときに便利です。 }HostNameの直後で| Export-Csvの前に次のように配置するだけです:... Sort RecordType, HostName }

1
Shad