Is the following possible in PowerShell: "Select-Object <Property>. <SubProperty>"?
Scenario: I use Select-Object to access the properties of an object with channels, and one of these properties is itself an object. Let me call it PropertyObject. I want to access the property of this PropertyObject, say Property1. Is there a nice and clean way to access Property1, line by line:
...| select-object PropertyObject.Property1 During the experiment, I can make it work if I am something like:
...| select-object {$_.PropertyObject.Property1} and if I want to display it with a decent column name, it gets even messier:
...| select-object @{Name="Property1"; Expression={$_.PropertyObject.Property1}} Given how clean and concise PowerShell is in general, I can't help but think that I am missing something, and there should be a cleaner way to access the property of the property. There is?
EDIT: As requested by Matt, here is a concrete example:
I am reading an XML file, Books3.xml:
<?xml version="1.0"?> <catalog> <book id="bk101"> <author>Gambardella, Matthew</author> <title>XML Developer 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> Code for loading XML in an XmlDocument:
$filePath = "C:\Temp\books3.xml" $xmlDoc = new-object xml $xmlDoc.load($filePath) Trying to read information for each book:
$xmlDoc.catalog.book | select author, title, publisher.name Result:
author title publisher.name ------ ----- -------------- Gambardella, Matthew XML Developer Guide Ralls, Kim Midnight Rain Corets, Eva Maeve Ascendant It would be easier if we had something real, repeatable for testing, but we can fake it with a Get-Item return.
(Get-Item C:\temp\logoutput).Parent.Name .Parent is actually a System.IO.DirectoryInfo object. I use PowerShell 3.0 notation to get name parent
The same result can be obtained by chaining select calls.
Get-Item C:\temp\logoutput | select -expand Parent | Select -Expand name This, of course, will work in PowerShell 2.0, but is not a succinct version and version 3.0.
Edit question
Not sure what you are hoping for. You have the job of extracting additional properties as you have. I can only offer an alternative approach, which may 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 may need to use select to access your resources only for the properties you need, but this is another option.
You can use calculated properties . In short, this will allow:
$xmlDoc.catalog.book | select author, title, {$_.publisher.name} If property names are important, you must add them.
$xmlDoc.catalog.book | select author, title, @{N="PublisherName";E={$_.publisher.name}} Where N is short for the name and E is short for expression.
I was also on the hunt for how to select the sub-properties of an object. In my case, this was to export DNS zone data. I will talk about what I used to achieve my goal, and this post helped here!
To accomplish what you were looking for, try changing your code as follows:
$xmlDoc.catalog.book | Select Author, Title, -Expand Publisher | Select Author, Title, Name | Sort Author | FT -auto Based on the output from the table, you indicated that the above should work. This worked for me, as you will see below.
This script worked perfectly on what I needed and is a mixture of different ideas. Hope this 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 convenient when you view the result before exporting. Just put } immediately after HostName and before | Export-Csv | Export-Csv as follows: ... Sort RecordType, HostName }