Why is this label not recognized?

In the following PS script, the innerloop label is not recognized as a valid part of the language.  What's going on and how do I fix this?
$totaltime=0;$mintime=99999999;$maxtime=0;$count=100;$MV="";
:outerloop for ($i=1; $i -le $count; $i++)
{$starttime=get-date
:innerloop foreach-object -process{$MV = $_.Installedon; break innerloop} -inputobject $GHF;
$TS= New-timespan -Start $starttime;  $thisTime=$ts.TotalMilliseconds; if ($thisTime -lt $mintime){$mintime=$thisTime}; if ($thisTime -gt $maxtime){$maxtime=$thisTime}; $totaltime=$totaltime+$thistime};
"For Each: " + $MV,"`tTotal Time: " + $totaltime + "ms;", "`tMin Time: " + $mintime + "ms;","`tMax Time: " + $maxtime + "ms;", "`tAvg Time: " + $totaltime/$count + "ms"

Open in new window


PS version = 2

===================
edited: corrected typo, caught by footech
LVL 47
aikimarkAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

SubsunCommented:
I could see Loop label does not work with Foreach-Object, May be because It accepts data from pipeline... You can try replacing it with Foreach loop
:innerloop foreach ($obj in $GHF) {$MV = $obj.Installedon; break :innerloop}

Open in new window

0
aikimarkAuthor Commented:
Both accept stream input.  The Foreach works.  

I do not seek a work-around, but an understanding of this phenomenon.
0
SubsunCommented:
Foreach wont accept pipeline output.. only foreach-object does..
0
What were the top attacks of Q1 2018?

The Threat Lab team analyzes data from WatchGuard’s Firebox Feed, internal and partner threat intelligence, and a research honeynet, to provide insightful analysis about the top threats on the Internet. Check out our Q1 2018 report for smart, practical security advice today!

aikimarkAuthor Commented:
Not true.  This works:
$totaltime=0;$mintime=99999999;$maxtime=0;$count=100;$MV="";
for ($i=1; $i -le $count; $i++)
{$starttime=get-date; 
foreach($g in $GHF){$MV = $g.Installedon; break}; 
$TS= New-timespan -Start $starttime;  
$thisTime=$ts.TotalMilliseconds; 
if ($thisTime -lt $mintime){$mintime=$thisTime}; 
if ($thisTime -gt $maxtime){$maxtime=$thisTime}; 
$totaltime=$totaltime+$thistime}; 
"For Each: " + $MV,"`tTotal Time: " + $totaltime + "ms;", "`tMin Time: " + $mintime + "ms;","`tMax Time: " + $maxtime + "ms;", "`tAvg Time: " + $totaltime/$count + "ms"

Open in new window

Besides...your comment does not address my label question.
0
SubsunCommented:
What you man by 'Not true'? are you saying there is no difference between Foreach-Object and foreach?

As per my knowledge foreach (Which is a looping construct) and ForEach-Object is a cmdlet (It also has alias foreach and %). Difference is that the First one generates the entire collection specified in the pipeline before processing it. On the other hand Foreach-Object gets one object once by one from pipeline and pass in on.

Regarding the label, As per the MS documentation Foreach-Object doesn't support label. See the exerts from following article.
Ref  : http://technet.microsoft.com/en-us/library/hh847873.aspx
The label is a colon followed by a name that you assign. The label must be the first token in a statement, and it must be followed by the looping keyword, such as While.
 
    In Windows PowerShell, only loop keywords, such as Foreach, For, and While can have a label.
0
aikimarkAuthor Commented:
What you man by 'Not true'?
I was referring to your prior comment:
Foreach wont accept pipeline output

Both of these looping statements process streamed data.

=============
only loop keywords, such as
I read that documentation as well.  It isn't clear whether this is a comprehensive list or not.
0
SubsunCommented:
As per y understanding all loop keywords (Do, Foreach, For, or While.) support label, Foreach-Object is a cmdlet and it doesn't support. I don't have any further comments.. Probably other experts can give you more comprehensive proof..
0
footechCommented:
I don't know if I have anything to add, except to back up what Subsun stated.
The foreach statement (as opposed to the ForEach-Object cmdlet) does not work with the pipeline.  There is nothing in the post http:#a40262406 that uses the pipeline.

foreach, for, do, while, and I think switch (sometimes?) are the only looping statements that I know of.  By the way to break out of a labelled loop, there's no colon in front of the label name used with the break statement.
:innerloop foreach ($a in $b){#do something; break innerloop}
                                                   ^
                                     no colon here ^

Open in new window

0
aikimarkAuthor Commented:
@foo

Thanks for catching my typo (now corrected).  I had tried several variations in the syntax and, unfortunately, pasted that one.  According to the documentation, the foreach conditionally becomes a foreach-object (or vice versa).  I can pipe the $GHF stream into both of these.  I've used the flavor of each statement in order to  try and label them, facilitating the break.  What I was getting with the foreach-object is a break out of the outermost looping construct.

I know that I can wrap both statements in a function, but I'm trying to avoid adding that overhead.  I'm giving a presentation next Wednesday at the local PS meetup and the version of the script I posted was the simplest.  It executes the simplest version of the code.  I know that I can execute these individually, outputting the totalmilliseconds values.  However, this introduces unnecessary I/O to the performance test.

I have three other bits of PS script that accomplish the same thing, but they do not require a break.  I want an apples-to-apples comparison of all of these with the least amount of overhead as possible.
0
footechCommented:
Yes, depending on the surrounding code/syntax, "foreach" could be either the foreach statement or ForEach-Object cmdlet.  There's no way you could type ForEach-Object and have it be the foreach statement though.
foreach (.. in ..){..}  <-always the foreach statement
.. | foreach {..}    <-always the foreach-object cmdlet
Since the break statement only works with looping statements, and not the ForEach-Object cmdlet, that is why a break included in the scriptblock of ForEach-Object would break out of any loop that contained the ForEach-Object construct, or if there wasn't one, would halt execution of the script.

I can pipe the $GHF stream into both of these.
Can you show me?  I think then I could clear up any confusion.  If you mean foreach($g in $GHF){$MV = $g.Installedon; break} - that is not using the pipeline.
0
aikimarkAuthor Commented:
Here is the simplest form of piping a stream into both the foreach and the foreach-object functions/statements.
PS C:\Users\Mark> $pt=""

_____________________________________________________________________________
PS C:\Users\Mark> $GHF | foreach{$PT = $g.Installedon; break}

_________________________________________________________________________________
PS C:\Users\Mark> $pt

Tuesday, November 20, 2012 12:00:00 AM

_________________________________________________________________________________
PS C:\Users\Mark> $pt=""

_________________________________________________________________________________
PS C:\Users\Mark> $GHF | foreach-object -process{$PT = $g.Installedon; break}

_________________________________________________________________________________
PS C:\Users\Mark> $pt

Tuesday, November 20, 2012 12:00:00 AM

Open in new window

0
aikimarkAuthor Commented:
If you want to see this on your system, $GHF = get-hotfix
0
footechCommented:
Both of those are using the ForEach-Object cmdlet, the first one just happens to be using the alias instead of the full name.
0
aikimarkAuthor Commented:
I assumed that to be the case from the documentation.

As you see, I can break out of these.  The problem comes in when I am trying to execute these nested under an iterator for construct.  The break kills both loops and a label seemed to be the only way to only break out of the inner loop.
0
footechCommented:
In those cases (where there isn't a looping statement), the break statement isn't really halting the ForEach-Object processing, it is halting execution of the entire script/command.
0
footechCommented:
You just need to get away from the idea that ForEach-Object is a loop, even though it does many of the same things.  Thus it is transparent to any type of break statement.
0
aikimarkAuthor Commented:
Thanks, foo.  Can you point me to the PS documentation or article/blog about that?

Time is running out on my prep for the Wednesday night PS meetup presentation, so I have to 'let go' of my attempt to compare statements this way.
0
footechCommented:
Nothing I can point to off-hand.  I think the help for about_foreach is misleading.  In my opinion they should have completely separated the ForEach-Object syntax guidance (i.e. not included it at all in that topic).  The entire section "The Foreach Statement Inside a Command Pipeline" applies to the ForEach-Object cmdlet and should have only been included in the help for that cmdlet.   The difference between foreach and ForEach-Object is a source of confusion for many beginners.  I assume you've also read the help for about_break.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
aikimarkAuthor Commented:
yes.  It was as fuzzy/nebulous as the foreach description.
0
footechCommented:
I felt it described things pretty well as long as you realize ForEach-Object isn't a looping keyword.
0
footechCommented:
I think we've pretty well covered all the topics in this question.  It's probably a good idea to go ahead and close it.
0
aikimarkAuthor Commented:
The PS presentation went well.  Thanks for your help in my construction of the code for the presentation.

I will add for future readers that the ForEach is an alias for Foreach-object in certain circumstances.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.