Michael
Michael

Reputation: 2942

Variables in nested Foreach-Object and Where-Object

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.

Upvotes: 46

Views: 55248

Answers (4)

Mike Anthony
Mike Anthony

Reputation: 464

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:_

Upvotes: 0

Phil Thompson
Phil Thompson

Reputation: 21

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 }

Upvotes: 2

Matt
Matt

Reputation: 46710

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.

Upvotes: 14

Lieven Keersmaekers
Lieven Keersmaekers

Reputation: 58441

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 { $_ .... }
}

Upvotes: 70

Related Questions