Public/Find-XmlNodes.ps1

<#
    .SYNOPSIS
    Recursively search the property we are looking for a specific value of.

    .DESCRIPTION
    Recursively search the property we are looking for a specific value of.
    Regardless the xml is RSOP results or others.

    .PARAMETER nodes
    xmlnode which need be searched.

    .PARAMETER foundWhere
    Use this parameter to control search for element or return value.

    .PARAMETER Where
    Element name which looking for.

    .PARAMETER Is
    Element content which looking for.

    .PARAMETER Return
    Element content would be return.

    .EXAMPLE
    $xmlnodes = $xmlDoc.DocumentElement.SelectNodes($QueryString, $XmlNameSpaceMgr)
    Find-XmlNodes -nodes $xmlnodes[0] -Where 'Name' -Is 'BatMan' -Return 'Vehicle'
    It searches the xmlnode, and referes the global variables '$Where $Is $Return'.
    Since the example defines $Return, it would return the 'Vehicle' element content.

   .INPUTS
    xmlnode which need be searched.

    .OUTPUTS
    If $Return defines, function returns the element content.
    If $Return does not define, returns $true if element could be found.
#>


function Find-XmlNodes {
    [CmdletBinding(DefaultParameterSetName = 'nodes')]
    [Alias()]
    [OutputType([int])]
    param(
        [Parameter(Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0,
            HelpMessage = 'xmlnode which need be searched')]
        $nodes,
        [bool] $foundWhere = $false,
        [Parameter(Mandatory = $true, HelpMessage = 'Extension element name which looking for')]
        [ValidateNotNullOrEmpty()]
        [string] $Where,
        [Parameter(Mandatory = $true, HelpMessage = 'Extension element content which looking for')]
        [ValidateNotNullOrEmpty()]
        [string] $Is,
        [string] $Return = $null
    )

    begin {
    }

    process    {
        $thePropertyWeWant = $Where

        # If we already found the $Where then we are looking for our $Return value now.
        if ($foundWhere) {
            $thePropertyWeWant = $Return
        }

        foreach ($node in $nodes) {
            $valueWeFound = $null

            #Here we are checking siblings
            $lookingFor = Get-Member -InputObject $node -Name $thePropertyWeWant

            if ($lookingFor -ne $null) {
                $valueWeFound = $node.($lookingFor.Name)
            }
            else {
                #Here we are checking attributes.
                if ($node.Attributes -ne $null) {
                    $lookingFor = $node.Attributes.GetNamedItem($thePropertyWeWant)


                    if ( $lookingFor -ne $null) {
                        $valueWeFound = $lookingFor
                    }
                }
            }

            if ( $lookingFor -ne $null) {
                #If we haven't found the $Where yet, then we may have found it now.
                if (! $foundWhere) {
                    # We have found the $Where if it has the value we want.
                    if ( [String]::Compare($valueWeFound, $Is, $true) -eq 0 ) {
                        # Ok it has the value we want too. Now, are we looking for a specific
                        # sibling or child of this node or are we done here?
                        if ($Return -eq $null -or $Return -eq '') {
                            #we are done, there is no $Return to look for
                            return $true
                        }
                        else {
                            # Now lets look for $Return in the siblings and then if no go, the children.
                            Find-XmlNodes -nodes $node -foundWhere $true -Where $Where -Is $Is -Return $Return
                        }
                    }

                }
                else {
                    #we are done. We already found the $Where, and now we have found the $Return.
                    if (! [String]::IsNullOrEmpty($node.InnerXml)) {
                        Find-XmlNodes -nodes $node.ChildNodes -foundWhere $foundWhere -Where $Where -Is $Is -Return $Return
                    }
                    else {
                        return $valueWeFound
                    }
                }
            }

            if (! [String]::IsNullOrEmpty($node.InnerXml)) {
                Find-XmlNodes -nodes $node.ChildNodes -foundWhere $foundWhere -Where $Where -Is $Is -Return $Return
            }
        }
    }

    end {
    }
}