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.
Select-Objectworks, basically. An expression likeSelect Nameis valid, but results in nothing becauseSelect-Objecttakes its input from the pipeline, unless-InputObjectis used. Since there is no pipeline in yourforeachloops, or in the blocks you pass toForEach-Object, there is no output. Using-InputObjectyou can get each of your examples to output something, although there would be little point since it's just more verbose.$s4a | select Nameor$s4a.Name