Is the following possible in PowerShell: "Select-Object <Property>.<SubProperty>"?

You can use calculated properties. A short form would allow for this:

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

If the property names are important you need to add them in.

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

Where N is short for name and E is short for expression.


It would be easier if you had something actual repeatable for us to test but we can fake that with Get-Items return.

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

.Parent is actually a System.IO.DirectoryInfo object. I use PowerShell 3.0 dot notation to get the name of the parent

The same result can be acquired by chaining the select calls

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

This of course would work in PowerShell 2.0 but is not a terse and the 3.0 version.

Post Question Edit

Not sure what you are hoping for. What you have does work at extracting sub properties the way you have it. I can only offer an alternate approach that might be more intuitive and friendly but the result is the same.

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

Of course you might still need to use select to get your output restricted to the properties you need but it is another option.


I too was on the hunt for how to accomplish a select of an object's sub-property. In my case it was in order to export a DNS Server's Zone data. I'll share the guts on what I used to accomplish my goal and this posting here helped!

To do what you were looking for specifically try modifying your code as follows:

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

Based on the table output you provided the above should work. It worked for me which you'll see below.

This script worked great for what I needed and is a blend of different ideas. Hopefully it works for someone else.

$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"
}

The Yellow Foreground is handy when you're looking at the output prior to export. Just put the } right after HostName and before | Export-Csv like this: ... Sort RecordType, HostName }