0

i was trying to loop through a list of file names in $s4a using ForEach and ForEach-Object and display output. The only two ways i found that generate output are:

  • ForEach ($name in $s4a) {$name.Name}
  • $s4a| ForEach-Object {$_ | Select Name}

Can someone please let me know why the ones below generate nothing, while the above two work?

  • ForEach ($name in $s4a) {Select Name} #No result
  • ForEach ($name in $s4a) {Select $name.Name} #No result
  • $s4a| ForEach-Object {Select$_.Name} #No result
  • $s4a| ForEach-Object {Select Name} #No result

Thanks heaps!

4
  • 2
    Well, because that's not how Select-Object works, basically. An expression like Select Name is valid, but results in nothing because Select-Object takes its input from the pipeline, unless -InputObject is used. Since there is no pipeline in your foreach loops, or in the blocks you pass to ForEach-Object, there is no output. Using -InputObject you can get each of your examples to output something, although there would be little point since it's just more verbose. Commented Jul 25, 2022 at 14:13
  • Does this answer your question? Difference between select-object and using foreach on the same object Commented Jul 25, 2022 at 14:13
  • 1
    thanks @jrider for sharing the link - it looks to me "Select -InputObject " can essentially replace ForEach loop in listing out elements inside a variable and hopefully improve on performance? Commented Jul 25, 2022 at 22:48
  • 1
    Correct, if you are just needing to display members of your object, a simple select statement is much faster. Also, if you want to get fancy with it you should look into select calculated properties. In your case just put $s4a | select Name or $s4a.Name Commented Jul 26, 2022 at 11:40

1 Answer 1

1

Essentially, it's because your syntax is incorrect for each of the statements that aren't working. In each of the non-working examples, you are not properly referencing the object that you wish the view the 'name' property on.

Select-Object is generally used when accepting an input object from the pipeline but can also identify the object using the -InputObject parameter.

When calling an object property by $object.propertyName, you don't need a select statement.

Instead of ForEach ($name in $s4a) {Select Name}, try this: ForEach ($name in $s4a) {$name | Select Name}

Instaed of ForEach ($name in $s4a) {Select $name.Name}, try this: ForEach ($name in $s4a) {$name.Name}

Instead of $s4a| ForEach-Object {Select$_.Name}, try this: $s4a| ForEach-Object {$_.Name}

Instead of $s4a| ForEach-Object {Select Name}, try this: $s4a| ForEach-Object {$_ | Select Name}

Also, please note that there is a difference in how each method returns information. Select statements return modified versions of the original objects that only contain the properties that you are selecting. Whereas, calling a property directly returns only the value of that property.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks so much Ian-Mor! this is really helpful and much appreciate the detailed explanation. do you mind if i ask if it's correct say you should never us "Select $object.propertyName" in any instance? i kinda recall seeing this expression somewhere before but unsure how it worked, if you would have any idea?
Another question if you wouldnt mind - can "Select -InputObject " basically replace ForEach/ForEach-Object loop if i were to simply list out elements inside a variable? this way a loop is saved and performance is faster i assume?
If you want to view a property, you can just call it directly: "$object.propertyName".

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.