I know only only one method to exit from Process phase or break pipeline -
Break command, but this command doesn't return anything to calling variable,
only to next pipeline:
1..5 | first2 | %{$_}
Any help is appreciated.
--
WBR, Vadims Podans
PowerShell blog - www.sysadmins.lv
1..10 | Linq-First { $_ -gt 5 } # returns 6
##############################################################################
#.Synopsis
# Returns the first element in a sequence that satisfies a specified
condition.
#
#.Parameter Predicate
# A function to test each element for a condition.
#
#.Example
# 1..10 | Linq-First { $_ -gt 5 }
#
#.ReturnValue
# The first element in the sequence that passes the test in the specified
# predicate or nothing if no elements pass the test.
##############################################################################
filter Linq-First([ScriptBlock]$Predicate) {
if ( $_ -eq $null ) { return }
if ( $Local:Result ) { return }
if ( &$Predicate ) {
$Local:Result=$true
$_
}
}
"Vadims Podans" <vpodans> wrote in message
news:D62FBE0D-9F80-47A5...@microsoft.com...
{some data collection} | first 5 - should return only first 5 objects (my
function does this)
$a = {some data collection} | first 5 - should write these first 5 objects
to $a variable. And here I have some troubles with my function. These
objects are streamed to next pipeline, but not to variable.
--
WBR, Vadims Podans
PowerShell blog - www.sysadmins.lv
"Josh Einstein" <joshei...@hotmail.com> rakstīja ziņojumā
"news:F0677FF1-BF19-4A06...@microsoft.com"...
I've filed a *bug* on connect last year regarding that behaviour, you may
want to vote on it:
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=332685&SiteID=99
# stream output to a variable or down the pipe.
function Select-First {
param([int]$num=2)
Begin {
[int]$i=0
}
Process {
if ($i -lt $num) {$i++; $_}
}
}
# save results to a variable (deafult value of first 2)
PS > $a=1..10 | Select-First
PS > $a
1
2
PS 7> 1..5 | Select-First -n 3 | foreach {$_}
1
2
3
---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar
Vv> I want to get N first objects. And here might be any type objects.
Vv> Like Select -first N, but Select doesn't break pipeline. something
Vv> like this:
Vv>
Vv> {some data collection} | first 5 - should return only first 5
Vv> objects (my
Vv> function does this)
Vv> $a = {some data collection} | first 5 - should write these first 5
Vv> objects
Vv> to $a variable. And here I have some troubles with my function.
Vv> These
Vv> objects are streamed to next pipeline, but not to variable.
Vv> "Josh Einstein" <joshei...@hotmail.com> rakst?ja zi?ojum?
Vv> "news:F0677FF1-BF19-4A06...@microsoft.com"...
Vv>
Assuming your example is generic there are several things you could
mean.
PS 20> $a = 1..5|Select-Object -first 3
PS 21> $a
1
2
3
This behavior can be duplicated like this
PS 23> function FirstN ([int]$count = 2) {
>> process {if ($count-- -gt 0){$_}}}
>>
PS 24> 1..6|firstn
1
2
PS 25> $a = 1..6|firstn
PS 26> $a
1
2
If you truly want to stop the pipeline at some point (AFAIK) the only
way is to throw.
The problem with throwing is that you then need to catch/trap the
throw or your routine fails.
If that weren't bad enough, the item you throw on will be lost unless
your catch knows how to retrieve it.
As an example, I wanted to find a very specific file that might be
anywhere on the drive.
DIR C:\* -I $name -R
This would usually find the file pretty quickly but then it would
continue searching the entire drive for more copies (which took a long
time) even though no more copies existed and I really didn't care if
they did.
&{trap {$_.TargetObject;continue} DIR C:\* -I $name -R|%{throw $_}}
This simply throws the item I'm looking for and I catch it and go on.
If I wanted to only emit the first 10 files matching a pattern I have
combinations of these choices.
I could wait for the 11th item to be found before throwing, thus
emitting normally and/or processing the first 10 before the throw that
kills the pipeline.
I could accumulate all the desired items and throw them so I could
process them after catching or trapping the error.
Or I could nest pipelines where the inner one is stopped at the
appropriate time so it stops emitting to the outer pipeline which can
then execute normally.
I will try to find a workaround which helps to acheive all goals. In any
case - thank you for help!
--
WBR, Vadims Podans
PowerShell blog - www.sysadmins.lv
"Shay Levy [MVP]" <n...@addre.ss> rakstīja ziņojumā
"news:95d80893704f78...@news.microsoft.com"...
"Kiron" <Ki...@HighPlainsDrifter.com> rakstīja ziņojumā
"news:DC7CF498-6F4C-401C...@microsoft.com"...
Josh
"Shay Levy [MVP]" <n...@addre.ss> wrote in message
news:95d80893704f78...@news.microsoft.com...
PS >$i=$null
PS >for (;$global:i++){return $i}
PS >for (;$global:i++){return $i}
2
PS >for (;$global:i++){return $i}
3
PS >write $i
3
PS >foreach-object -process{
$Global:MyVal = for (;$i++){return $i}}
4
PS >foreach-object -process{
$Global:MyVal = for (;$i++){return $i}}
5
PS >write $MyVal
[no value returned]
Truthfully it should probably return an error when you try to do that. What
is happening is the return statement is returning from the scriptblock that
you're passing to the ForEach cmdlet. In other words, the foreach statement
does not add a frame to the call stack from which you can return. If you
tried that in C# for example it wouldn't even compile.
private object ForEachCmdlet(this IEnumerable sequence, Func<object> body) {
var x = foreach ( object o in sequence ) { // this line wouldn't
compile
object ret = body(o);
if ( ret != null ) {
return ret; // returns from the method, not the foreach loop
}
}
}
"rferrisx" <rfe...@rmfdevelopment.com> wrote in message
news:a52815f1-e724-4764...@i2g2000prd.googlegroups.com...
I didn't metion it on my response, the function I posted wasn't for breaking
the pipeline it
was meant to solve your variable assignment.
---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar
Vv> Hy, Shay!
Vv> I vote on connect. I see that your script only returns first two
Vv> objects,
Vv> but doesn't break a pipeline:
Vv> [vPodans] (measure-command {gwmi win32_ntlogevent -filter
Vv> "logfile='system'"
Vv> | select-first 1}).totalseconds
Vv> 44,5870382
Vv> [vPodans] (measure-command {gwmi win32_ntlogevent -filter
Vv> "logfile='system'"
Vv> | select -first 1}).totalseconds
Vv> 45,6124848
Vv> I will try to find a workaround which helps to acheive all goals. In
Vv> any case - thank you for help!
Vv>
Vv> "Shay Levy [MVP]" <n...@addre.ss> rakst?ja zi?ojum?
Vv> "news:95d80893704f78...@news.microsoft.com"...
Vv>
I agree. The only thing that has to stop (skip) is the process block of the
cmdlet in question, processing should continue to the end block.
---
Shay Levy
Windows PowerShell MVP
http://blogs.microsoft.co.il/blogs/ScriptFanatic
PowerShell Toolbar: http://tinyurl.com/PSToolbar
JE> If they accept that as a bug, then I think they should also make it
JE> execute EndProcessing (unless the break occurred while inside of
JE> EndProcessing). My other post "Any plans for StopProcessing..."
JE> talks about the problems this causes if you count on your End blocks
JE> to do cleanup. There should be some equivalent of a "finally" for
JE> pipelines.
JE>
JE> Josh
JE>
JE> "Shay Levy [MVP]" <n...@addre.ss> wrote in message
JE> news:95d80893704f78...@news.microsoft.com...
JE>
for what its worth what I've been able to determine is the type being used
to flow the data result from ArrayList::GetEnumerator(). There is however an
override GetEnumerator(int, int) what is missing is how to say this in your
script.
perhaps a
blob | foreach_n <count> { ..... }
would work.
and output:
[↓] [vPodans] 1..5 | Select-First 3
1
2
3
[↓] [vPodans] 1..5 | Select-First 3 | select -First 2
1
2
[↓] [vPodans] $c = 1..5 | Select-First 3
[↓] [vPodans] $c
1
2
3
[↓] [vPodans] $c = 1..5 | Select-First 3 | select -First 2
[↓] [vPodans] $c
1
2
3
[↓] [vPodans]
As previous script this function stream his output to pipeline. And assign
selected data to calling variable and stream output to next pipeline.
However next pipeline doesn't change this variable:
[↓] [vPodans] filter input {$_ * 2 | out-default}
[↓] [vPodans] $c = 1..5 | Select-First 3 | input
2
4
6
[↓] [vPodans] $c
1
2
3
[↓] [vPodans]
here I see that objects are streamed to pipeline, but they lost in pipe
(variable $c will not changed even if data is changed in next pipelines). I
assume that this due breaked pipeline.
--
WBR, Vadims Podans
MVP: PowerShell
PowerShell blog - www.sysadmins.lv
"Kiron" <Ki...@HighPlainsDrifter.com> rakstīja ziņojumā
"news:DC7CF498-6F4C-401C...@microsoft.com"...
[5]: $c = 1..5 | select-first 3 | input
2
4
6
The '=' operator failed: System error..
At line:1 char:5
+ $c = <<<< 1..5 | select-first 3 | input
[6]: $c
1
2
3
In Windows 7 RC I'm not seeing the error, but $Error does get a new
instance of System.Management.Automation.BreakException (the text is
just "System Error.")
--
Joel Bennett
The pipeline has been stopped.
At :line:1 char:128
+ function PipelineBreakpointerE4078E3092DF4dd9A469F3DC0CBB505C([int]
$offset){BEGIN {} PROCESS {$host.SetShouldExit($offset); $_} <<<< END
{}};$vE4078E3092DF4dd9A469F3DC0CBB505C={Remove-PSBreakPoint -BreakPoint
$bE4078E3092DF4dd9A469F3DC0CBB505C;Remove-Variable
vE4078E3092DF4dd9A469F3DC0CBB505C;Remove-Variable
bE4078E3092DF4dd9A469F3DC0CBB505C;
--
WBR, Vadims Podans
MVP: PowerShell
PowerShell blog - www.sysadmins.lv
"Joel Bennett" <Jay...@HuddledMasses.org> rakstīja ziņojumā
"news:OpiJZvoA...@TK2MSFTNGP05.phx.gbl"...
"Robert Robelo" <Ki...@HighPlainsDrifter.com> rakstīja ziņojumā
"news:ubQBhFxA...@TK2MSFTNGP03.phx.gbl"...
"Robert Robelo" <Ki...@HighPlainsDrifter.com> rakstīja ziņojumā
"news:ubQBhFxA...@TK2MSFTNGP03.phx.gbl"...
just put this script to Task Scheduler and have a nice day :)
I have a copy of this conversation and will try again in this.
--
WBR, Vadims Podans
MVP: PowerShell
PowerShell blog - www.sysadmins.lv
"Robert Robelo" <Ki...@HighPlainsDrifter.com> rakstīja ziņojumā
"news:e8r9ijyA...@TK2MSFTNGP03.phx.gbl"...