Powershell : multiple Select-Object statements returning 1st occurrence results only

344 views Asked by At

I am running PowerShell version 4.0 on Windows 8.1

I have an xml document (from a nifi flow) called flow1.xml as follows:

<flowController encoding-version="1.3">
  <rootGroup>
    <id>123</id>
    <name>BigTime</name>
    <position x="0.0" y= "0.0"/>
    <processGroup>
      <id>456</id>
      <name>SmallTime</name>
      <position x="1000.0" y="2000.0"/>
      <processGroup>
        <id>789</id>
        <name>TinyTime</name>
        <position x="3000.0" y="4000.0"/>
      </processGroup>
    <processGroup/>
  </rootGroup>
</flowController>

I have a powerShell script test.ps1 as follows :

$filePath='flow1.xml'
$xmlDocument = New-Object -TypeName XML
$xmlDocument.Load($filePath)

$xmlDocument.flowController.rootGroup.processGroup |
Where-Object { $_.name -eq 'SmallTime'} |
Select-Object -Property {$_.id}

$xmlDocument.flowController.rootGroup.processGroup.processGroup |
Where-Object { $_.name -eq 'TinyTime'} |
Select-Object -Property {$_.id}

I run from PowerShell within a Windows Cmd box; ie PS C\Temp>test.ps When I run this I get output as expected:

Output:
$_.id
-----
456
789

When I change the 2nd Select_Object thus :

$xmlDocument.flowController.rootGroup.processGroup.processGroup |
Where-Object { $_.name -eq 'TinyTime'} |
Select-Object -Property {$_.name}

I get

Output:
$_.id
-----
456

I get only the $_id from the 1st clause, but not the $_name from the 2nd clause. The general case is - if both Select-Object statements select the same parameter then both are executed correctly. For instance if both Select-Object statements were Select-Object -Property {$_.name} I get the output :

Output:
$_.name
-----
SmallTime
TinyTime

If the Select-Object statements are different it seems to only execute the first one. I tried reading in the xmlDocument again before the 2nd Select-Object :

$filePath='flow1.xml'
$xmlDocument = New-Object -TypeName XML
$xmlDocument.Load($filePath)

$xmlDocument.flowController.rootGroup.processGroup |
Where-Object { $_.name -eq 'SmallTime'} |
Select-Object -Property {$_.id}

$xmlDocument = New-Object -TypeName XML
$xmlDocument.Load($filePath)
$xmlDocument.flowController.rootGroup.processGroup.processGroup |
Where-Object { $_.name -eq 'TinyTime'} |
Select-Object -Property {$_.id}

but the same thing happens. I only get the result of the 1st Select-Object statement.

Does anyone know why this is happening?

2

There are 2 answers

0
mikec On BEST ANSWER

Just adding this note for closure.

Don't know what was going wrong with the piping. Colleagues have had similar problems. So I changed tack.

I drilled down into $xmlDocument by setting a new variable: $group = $xmlDocument.flowController.rootGroup.processGroup

and replaced the code with appropriate

foreach ($property in $group.property...){
   if ($property.name -eq 'oldValue'){
     parameter.value = 'newValue'
   }
}

This works, and can be further elaborated/complicated with more complex searches.

3
Ernest Correale On

This sounds rather like a homework assignment. The answers below treat it as such. In other words, these should help point out some of the issues but readers here shouldn't be doing your homework for you.

  • Please review the proper format of the pipeline variable. It's $_ not $
    e.g., $_.Name Google: PowerShell Pipeline Variable

  • Review the use of comparison operators. There is no such thing as .eq in PowerShell

  • Your XML is malformed so, I'm not sure how this script is even getting past $xmlDocument.Load() The syntax used to load the file looks good and you're on the right track to load property values. Once the XML is well-formed, all you'll need is to use the correct paths to the data.

  • You only need to read the XML in one time.

  • You don't need to use the pipeline variable with a select statement. Just the property name will suffice.
    e.g., Select-Object Name This will return the value of the Name property

I hope this enough to get you moving again.