PowerShell 3.0 introduced collection property enumeration as one of language
enhancements. That is, if $x is a collection then $x.Data1 gets values of
the property Data1 from all collection items.
This feature saves time in some cases. Obviously, $x.Data1 is the shortest of
these similar expressions:
$x.Data1
$x | .{process{$_.Data1}}
foreach($e in $x) {$e.Data1}
$x | ForEach-Object {$_.Data1}
$x | Select-Object -ExpandProperty Data1But this new feature has some cost. It became more difficult to troubleshoot
cases when $x is supposed to be a scalar by design but it is unexpectedly a
collection during invocation, for example due to Unexpected-output or other
mistakes.
Unlike in PowerShell 2.0, in such cases $x.Data1 is not null in the normal
mode and it is not always an error in the strict mode. Thus, the unexpected
collection and data may not reveal themselves at this point. Ironically,
$x.Data1 is an unexpected collection itself, so that even expressions like
$x.Data1.Data2 may not reveal that something is wrong at this point because
.Data2 is applied to the unexpected collection just fine.
The script Test-1-1-original-case-normal.ps1 is the simplified original reported script. It contains a mistake. With this mistake the code works without errors incorrectly and differently in v2 and v3+. In v2 it is less likely going to cause any harm before the mistake is found and fixed. Of course there may be cases when v2 is less safe but in general v3+ looks less safe.
The script Test-1-2-original-case-strict.ps1 is the same but it is invoked in the strict mode. Now the mistake is revealed immediately in v2. In v3 the code still works incorrectly with no errors.
A proper workaround is unlikely possible, such mistakes are inevitable and in
v3+ $x.Data1 is a valid expression even if $x is a collection by mistake.
But some sort of remedy exists. In some cases it looks safer to make checks
like $value -eq $x.Data1 instead of more traditional $x.Data1 -eq $value.
See Comparison-operators-with-collections for the details. Reversed checks
get false if $x and $x.Data1 are unexpected collections.
The script Test-1-3-safer-approach.ps1 shows that in v3+ the reversed check does not cause potentially unwanted processing of each item due to the mistake.
But the script Test-2-1-noise-data-normal.ps1 shows that even reversed checks may not reveal some unexpected noise data.
The script Test-2-2-noise-data-strict.ps1 shows that the strict mode may help in v3+, too, it reveals unexpected data which do not have expected properties.