Peter Jensen
Peter Jensen

Reputation: 3

Looping through XML hierarchy and get all nodes with specific properties

I have extracted some data from a solution which only supports some rather suspect XML exports. I need to traverse through the hierarchy in Powershell to list all objects of type="node", regardless of how deep they are in the hierarchy, that have the property "KeySecret" and return the value of the "name" property of this object, and the value of the "name" property of the parent object type="Domain" it belongs to.

Cant figure this out based on whatever select-xml -xpath i have tried.

Short and simple version of my XML

<?xml version="1.0"?>
<Object id="1.1622157565" type="Domain">
  <Property type="String" name="name" value="ROOTDOMAIN"/>
  <Object id="1.1131962319" type="Node">
    <Property type="String" name="name" value="AGENTLESS NODE 1"/>
  </Object>
  <Object id="1.1132169655" type="Domain">
    <Property type="String" name="name" value="SUBDOMAIN"/>
    <Object id="1.1132121638" type="Node">
      <Property type="BigNum" name="keySecret" value="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"/>
      <Property type="String" name="name" value="AGENT NODE 1"/>
    </Object>
  </Object>
</Object>

Any hints as to how to end up with this table:

Domain        Node
------        ------
SUBDOMAIN     AGENT NODE 1

Upvotes: 0

Views: 376

Answers (1)

Shamus Berube
Shamus Berube

Reputation: 486

Here is what I got so far. I hope it points you in the right direction.

[xml]$XML = @"
<?xml version="1.0"?>
<Object id="1.1622157565" type="Domain">
  <Property type="String" name="name" value="ROOTDOMAIN"/>
  <Object id="1.1131962319" type="Node">
    <Property type="String" name="name" value="AGENTLESS NODE 1"/>
  </Object>
  <Object id="1.1132169655" type="Domain">
    <Property type="String" name="name" value="SUBDOMAIN"/>
    <Object id="1.1132121638" type="Node">
      <Property type="BigNum" name="keySecret" value="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"/>
      <Property type="String" name="name" value="AGENT NODE 1"/>
    </Object>
  </Object>
</Object>
"@

$keyNode = $xml.SelectNodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | Where-Object {$_.Name -like "keySecret"} 

$keyParent = $keyNode

do {
    $keyParent = $keyParent.ParentNode
} 
Until ($keyParent.type -like "Domain")

$output = New-Object PSObject
$output | Add-Member -MemberType NoteProperty Domain ($keyParent.ChildNodes | Where-Object {$_.type -eq "String"}).Value
$output | Add-Member -MemberType NoteProperty Node $keyNode.NextSibling.value

$output

keyNode : selects all nodes from the XML that are like 'Name=' and then selects anything that is like 'keySecret'

The Do,Until loop will search up the Parent Nodes until the Parent Node type is 'Domain'. This will let you find a node buried deep in the hierarchy. The 'Domain' node is set as $keyParent.

Upvotes: 1

Related Questions