Piping is designed to process items immediately as they appear so the entire length of the list is not known while it's being piped.
Get-ChildItem $path -Directory | ForEach {
# PROCESSING STARTS IMMEDIATELY
# LENGTH IS NOT KNOWN
}
- Advantage: processing starts immediately, no delay to build the list.
- Disadvantage: the list length is not known until it's fully processed
On the other hand, assigning the list to a variable builds the entire list at this point, which can take an extremely large amount of time if the list contains lots of items or it's slow to build, for example, if it's a directory with lots of nested subdirectories, or a slow network directory.
# BUILD THE ENTIRE LIST AND ASSIGN IT TO A VARIABLE
$folders = Get-ChildItem $path -Directory
# A FEW MOMENTS/SECONDS/MINUTES/HOURS LATER WE CAN PROCESS IT
ForEach ($folder in $folders) {
# LENGTH IS KNOWN: $folders.count
}
- Advantage of building the list +
ForEach
statement: overall time spent is less because processing { }
block is not invoked on each item whereas with piping it is invoked like a function or scriptblock, and this invocation overhead is very big in PowerShell.
- Disadvantage: the initial delay in the list assignment statement can be extremely huge