在PowerShell中是否可以使用"Select-Object <Property>.<SubProperty>"的语法?

21

场景:我正在使用Select-Object来访问管道对象的属性,其中一个属性本身是一个对象。我们称之为PropertyObject。我想访问该PropertyObject的一个属性,比如Property1。有没有一种简洁明了的方式来访问Property1,类似于:

...| select-object PropertyObject.Property1

在尝试实验的时候,我只能通过做类似以下的操作才能使其起作用:

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

如果我想用一个合适的列名来显示它,那会变得更加混乱:

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

鉴于PowerShell通常非常干净简洁,我不禁想到我可能错过了某些内容,也许有更清晰的方法可以访问属性中的属性。有吗?

编辑: 根据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

1
你的PowerShell版本是多少?如果是3.0,你可以直接使用$object.PropertyObject.Property1。否则,你需要使用选择器链select PropertyObject | select Property1。你可能需要在其中添加一些扩展,但这就是要点。这都取决于属性。 - Matt
我进行了一次小的更新,但我不认为这是你要寻找的答案。提取单个属性比你要寻找的对象输出更容易。Select 是解决这个问题的方法。你可以通过将哈希移动到单个变量来简化它,但这并不改变所需的代码。 - Matt
3个回答

48

您可以使用计算属性。以下是一种简短的形式:

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

如果属性名称很重要,你需要将它们添加进去。

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

N代表名称,E代表表达式。


这实际上回答了楼主的问题。 - MartinThé

8

如果您有实际可重复测试的内容,那么对我们来说会更容易,但是我们可以通过 Get-Item 的返回值来模拟。

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

.Parent 实际上是一个 System.IO.DirectoryInfo 对象。我使用 PowerShell 3.0 的点符号语法来获取父目录的 name

通过链接 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 来限制输出到你所需的属性,但这是另一种选择。

1
我认为你的“发布问题-编辑答案”回答了我的问题:我不能像select author,title,publisher.name那样做,我必须做一些更复杂的事情才能获得出版商的名称。我正在学习PowerShell的工作原理,这正是我想要了解的。谢谢。 - Simon Elms

1
我也在寻找如何选择对象的子属性,以便导出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 }

尝试了一下,但是出现了以下错误:Select-Object: 无法找到接受 'publisher' 参数的位置参数。我想知道这是不是因为书籍对象的类型是System.Xml.XmlElement? - Simon Elms

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接