Question:
The following XML file is one Object node of the output from the command Get-ClusterGroup run from a 2008 R2 Failover Cluster with PowerShell 2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
The full file has three more Object nodes similar to this. Two of those nodes have the value “False” in the “IsCoreGroup” attribute and the other two are “True”. What I am trying to do is get the value of the “Name” property and other attributes from the Object nodes that have the value of “False” in the “IsCoreGroup” attribute.
I have tried a number of ways to get this attribute but can’t figure out how to drill down into the sibling attributes.
Here’s what I have so far:
1 2 3 4 5 6 7 8 9 10 |
[xml]$file = get-content C:\Admin\ClusterGroups.xml $xmlProperties = $file.SelectNodes("/Objects/Object/Property") Foreach ($xmlProperty in $xmlProperties) { $strName = ($xmlProperty | Where-Object {$_.Name -eq "IsCoreGroup" }).InnerXml If ($strName -eq "False") { Echo $xmlProperty } } |
This gives me the following:
1 2 3 4 |
Name #text ---- ----- IsCoreGroup False |
But I can’t figure out how to get the sibling properties
I tried backing up a level with:
1 2 3 4 5 6 7 8 9 10 |
[xml]$file = get-content C:\Admin\ClusterGroups.xml $xmlObjects = $file.SelectNodes("/Objects/Object") Foreach ($xmlObject in $xmlObjects) { $strCoreGroup = ($xmlObject | Where-Object {$_.Property.Name -eq "IsCoreGroup" }).InnerXml If ($strCoreGroup -eq "False") { Echo $xmlObject } } |
But that’s not getting me anywhere.
Any help is greatly appreciated!
Answer:
You need to access the parentnode if you’re variable points at a property-element. Since you need to find a property element where the name is a attribute-value, I prefer using xpath to do this.
1 2 3 4 5 6 7 8 9 10 |
$xmlProperties = $file.SelectNodes("/Objects/Object/Property") Foreach ($xmlProperty in $xmlProperties) { $strName = ($xmlProperty | Where-Object {$_.Name -eq "IsCoreGroup" }).InnerXml If ($strName -eq "False") { # .. means parent node. So the xpath goes up one level from property, and searches for the new property you want. $xmlProperty.SelectSingleNode('../Property[@Name="Name"]').InnerXml } } |
You could also have done $xmlproperty.parentnode.whateveryouwant
.
Personally I’d use xpath to search for the right objects to begin with and retrieve them at object-level, so you can easily access the other properties in the object-node without going up a level.
1 2 3 4 5 6 7 |
$file.SelectNodes('/Objects/Object[Property[@Name="IsCoreGroup"]="False"]') | % { #Foreach object with IsCoreGroup = false, get value of property with Cluster1 as Name attribute $_.SelectSingleNode('Property[@Name="Cluster"]').innerxml } Cluster1 |