47

I'm wondering how to work with nested Forach-Object, Where-Object and other Cmdlets in Powershell. For example this code:

$obj1 | Foreach-Object { 
    $obj2 | Where-Object { $_ .... }
}

So in the code block of Foreach-Object I use the elements of $obj1 as $_. But the same happenn in the code block of Where-Object with $obj2. So how can I access both objects elements in the Where-Object code block? I would have to do $_.Arg1 -eq $_.Arg1 but this makes no sense.

4 Answers 4

73

afaik, You'll need to keep a reference to the outer loop by putting it in a local variable.

$obj1 | Foreach-Object { 
    $myobj1 = $_
    $obj2 | Where-Object { $_ .... }
}
Sign up to request clarification or add additional context in comments.

Comments

15

Another way do address this is with a slighty different foreach

ForEach($item in $obj1){
    $obj | Where-Object{$_.arg -eq $item.arg}
}

Still boils down to about_Scopes. $_ is always a reference to the current scope. As you must know ($_.Arg1 -eq $_.Arg1) would just be refering to itself.

3 Comments

I know about a "real" foreach loop but I'm ssearching a solution for exactly this problem, because this happens in deferent situations. It could be without Foreach-Object too.
@Michael then you have to save the variable so that it is accessible to the other scopes like Lieven and I are suggesting.
@Matt, does $_ have a parent-object reference that can be used in these situations? Something like $itemArray | % { $_.childArray | % { $_.Parent.ParentProperty }}
2

If the match is simple enough, you can get rid of the inner code block and avoid a local variable.

$obj1 | Foreach-Object { 
    $obj2 | Where property -eq $_.property
}

e.g:

$array = ("zoom", "explorer", "notreal")
$array | foreach { get-process | where ProcessName -EQ $_ | Out-Host }

Comments

1

You can also use scopes nowdays, e.g. a foreach inside a foreach can be accessed with $_ and the parent foreach can be accessed within the child loop using $script:_

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.