Last active
May 11, 2021 21:14
-
-
Save mtboren/4f174c2d47ad4512168cace9f459d082 to your computer and use it in GitHub Desktop.
Example of pipeline difference between ForEach-Object cmdlet and foreach() statement in PowerShell
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<# | |
While we can iterate over objects with both ForEach-Object and the foreach() statement, only ForEach-Object emits objects | |
to the pipeline. The foreach() statement does _not_, which prevents us from doing any further cool things with objects | |
that might be created in the foreach() statement's scriptblock | |
Some examples: | |
#> | |
## no objects returned to pipeline, so we are done with the interesting things immediately | |
PS C:\> foreach ($intI in 1..10) {New-Object -Type PSObject -Property @{SomeCoolProperty = $intI}} | Measure-Object -Sum -Property SomeCoolProperty | |
At line:1 char:92 | |
+ … bject -Type PSObject -Property @{SomeCoolProperty = $intI}} | Measure … | |
+ ~ | |
An empty pipe element is not allowed. | |
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException | |
+ FullyQualifiedErrorId : EmptyPipeElement | |
## but, ForEach-Object puts our juicy objects on the pipeline so we can continue our interesting interactions with said objects | |
PS C:\> 1..10 | ForEach-Object {New-Object -Type PSObject -Property @{SomeCoolProperty = $_}} | Measure-Object -Sum -Property SomeCoolProperty | |
Count : 10 | |
Average : | |
Sum : 55 | |
Maximum : | |
Minimum : | |
StandardDeviation : | |
Property : SomeCoolProperty | |
## less natural / slightly more cumbersome, but we could, of course, create a new variable to hold the resultant objects, | |
# and in a subsequent command, do something with the objects | |
PS C:\> $arrTmp = foreach ($intI in 1..10) {New-Object -Type PSObject -Property @{SomeCoolProperty = $intI}} | |
PS C:\> $arrTmp | Measure-Object -Sum -Property SomeCoolProperty | |
Count : 10 | |
Average : | |
Sum : 55 | |
Maximum : | |
Minimum : | |
StandardDeviation : | |
Property : SomeCoolProperty | |
## and, we could use a subexpression "$(foreach(...) {...})" to eventually get objects on the pipeline, but that defeats the | |
# whole power of the pipeline principle in PowerShell :frownie_face: | |
## Example of using the power of the pipeline (and being done after just the first object) | |
## ~0.5 seconds when getting just the first object :thumbs_way_up: | |
PS C:\> Measure-Command {1..1000 | ForEach-Object {Start-Sleep -Seconds 0.5; $_} | Select-Object -First 1} | |
Days : 0 | |
Hours : 0 | |
Minutes : 0 | |
Seconds : 0 | |
Milliseconds : 506 | |
Ticks : 5061489 | |
TotalDays : 5.85820486111111E-06 | |
TotalHours : 0.000140596916666667 | |
TotalMinutes : 0.008435815 | |
TotalSeconds : 0.5061489 | |
TotalMilliseconds : 506.1489 | |
## Example of defeating one of the main purposes of the pipeline, causing _all_ objects to be considered before continuing | |
# on down the pipeline (the whole subexpression "$(...)" has to complete before any objects are then emitted down the pipeline) | |
## 8+ minutes to get just the first object! :thumbs_down: | |
PS C:\> Measure-Command {$(foreach ($intI in 1..1000) {Start-Sleep -Seconds 0.5; $intI}) | Select-Object -First 1} | |
Days : 0 | |
Hours : 0 | |
Minutes : 8 | |
Seconds : 20 | |
Milliseconds : 92 | |
Ticks : 5000923992 | |
TotalDays : 0.00578810647222222 | |
TotalHours : 0.138914555333333 | |
TotalMinutes : 8.33487332 | |
TotalSeconds : 500.0923992 | |
TotalMilliseconds : 500092.3992 | |
## and, as you see, these varied times are specific to further object consumption down the pipeline (the way that we get exactly what we want in PS) | |
# The overall run duration to get all 1000 objects in either of these ways is the same, but part of the point is that we do not | |
# always need all 1000 objects |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment