Exercise 2: Why $results.Count Is 0 After ForEach-Object -Parallel — Possible Solution ==================================================================== WHY $results ENDS UP EMPTY ------------------------------ Per this chapter's own central finding, every -Parallel iteration runs in its own genuinely isolated runspace - $results inside each of the five iterations is NOT the same $results variable that exists in the caller's own scope. Without $using:, $results is simply undefined inside each isolated runspace, so $results += $_ actually creates five separate, brand-new local variables - one per runspace - each one only ever holding that single iteration's own value. None of those five short-lived local variables is ever the original $results from the caller, and all five are discarded the instant their own iteration finishes. The caller's real $results was therefore never touched at all, which is why it still reports a Count of 0 afterward. THE ACTUAL FIX ------------------------------ Per this chapter, a genuinely thread-safe collection is required instead of a plain array - specifically [System.Collections.Concurrent.ConcurrentBag[object]]::new(), referenced inside the parallel block via $using:results, with .Add() called on it rather than using +=. Because a ConcurrentBag is built to be safely written to from multiple runspaces at once, and because $using:results correctly references the SAME shared object across every iteration (rather than each iteration getting its own disconnected copy), this actually accumulates all five results into the one real collection. WHY THIS WORKS AS AN ANSWER ------------------------------ It correctly explains that each -Parallel iteration's isolated runspace creates its own disconnected local variable rather than modifying the caller's actual $results, and correctly identifies a thread-safe collection (ConcurrentBag) accessed via $using: as the real fix, rather than just suggesting to remove -Parallel.