Try - Catch differences in foreach loop

Dear guys,

I’ve notices strage behaviour of the “try-catch” function.

For testing purposes I’ve stored to variable 2 random windows services with 2 properties - “name” and “displayname”. Then I’ve changed the property “name” on the second object in array to value “something”.

$services= get-service | select -first 2 name,displayname



Now, I want to achieve thru loop that when error appears, while trying to get service with the name “something” (in the “try” script block), it tries to get the service by property “displayname” (in catch scriptblock).


$services | foreach {

try {get-service $ -ErrorAction Stop} catch

{get-service $_.displayname}


The code above, failes to get the service by the value stored in the “$_.displayname” because it is empty… But in the code below it normally executes $s.displayname.

foreach ($s in $services) {

try {get-service $ -ErrorAction stop} catch

{get-service $s.displayname}


Can someone please explain why this is happening.




Well, $_ is the notation for Object passed through between cmdlets in a pipeline. But when you use Try{} Catch{}, $_ in catch is the Error details where ever you place it.

Try{Get-Process -Name NoProcess -ErrorAction Stop}
Try{Get-Process -Name NoProcess -ErrorAction Stop}
Catch{$_ | Get-Member}

When you use foreach statement(not ForEach-Object cmdlet), each object is not identified using $_, but its having its own temp variable which we give, here it is $S.

Thanks for the explanation :slight_smile: