![]() |
![]() | ![]() | ![]() | ![]() | ![]() | ![]() | ![]() |
| Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks. |
| |||||||
![]() |
| |
| | #1 (permalink) |
| | object pipeline? I've read that one of PowerShell's features is that the pipeline passes objects. That sounded useful so I tried to use the pipeline to pass an array. I tested this using an array of strings as the object with a filter to receive the array. What I found is that PowerShell doesn't seem to pass the array but instead passes each of values separately. Here's a tiny piece of code: filter disp { $inparm = [string[]]$_ $inparm | write-debug bp } [string[]]$a += "string1" [string[]]$a += "string2" $a |disp The breakpoint is reached twice. The first time, $inparam is string1; the second time it is string2. I had expected the breakpoint would be reached once and $inparam would be the array("string1", "string2"). What am I missing? If I change "filter" to "function" I get an error "Write-Debug : Cannot bind argument to parameter 'Message' because it is null." What does this mean? Thanks Mike |
My System Specs![]() |
| | #2 (permalink) |
| | Re: object pipeline? When you cahnge "filter" to "function" the $_ is not valid anymore and equels to $null. You need to change $_ to $args[0]. Shay http://scriptolog.blogspot.com Quote: > I've read that one of PowerShell's features is that the pipeline > passes objects. That sounded useful so I tried to use the pipeline to > pass an array. I tested this using an array of strings as the object > with a filter to receive the array. What I found is that PowerShell > doesn't seem to pass the array but instead passes each of values > separately. > > Here's a tiny piece of code: > > filter disp > { > $inparm = [string[]]$_ > $inparm | write-debug > bp > } > [string[]]$a += "string1" > [string[]]$a += "string2" > $a |disp > > The breakpoint is reached twice. The first time, $inparam is string1; > the second time it is string2. I had expected the breakpoint would be > reached once and $inparam would be the array("string1", "string2"). > > What am I missing? > > If I change "filter" to "function" I get an error "Write-Debug : > Cannot bind argument to parameter 'Message' because it is null." > > What does this mean? > > Thanks > > Mike > |
My System Specs![]() |
| | #3 (permalink) |
| | Re: object pipeline? There are other subtle difference between Function and Filter... Basically the way I understand it - Function collects all data in the pipe and processes it' - Filter is process as you go. More info get-help about_function "Shay Levi" <no@xxxxxx> wrote in message news:8766a94468ee8c9beece88e5d4e@xxxxxx Quote: > When you cahnge "filter" to "function" the $_ is not valid anymore and > equels to $null. > You need to change $_ to $args[0]. > > Shay > http://scriptolog.blogspot.com > > > Quote: >> I've read that one of PowerShell's features is that the pipeline >> passes objects. That sounded useful so I tried to use the pipeline to >> pass an array. I tested this using an array of strings as the object >> with a filter to receive the array. What I found is that PowerShell >> doesn't seem to pass the array but instead passes each of values >> separately. >> >> Here's a tiny piece of code: >> >> filter disp >> { >> $inparm = [string[]]$_ >> $inparm | write-debug >> bp >> } >> [string[]]$a += "string1" >> [string[]]$a += "string2" >> $a |disp >> >> The breakpoint is reached twice. The first time, $inparam is string1; >> the second time it is string2. I had expected the breakpoint would be >> reached once and $inparam would be the array("string1", "string2"). >> >> What am I missing? >> >> If I change "filter" to "function" I get an error "Write-Debug : >> Cannot bind argument to parameter 'Message' because it is null." >> >> What does this mean? >> >> Thanks >> >> Mike >> > |
My System Specs![]() |
| | #4 (permalink) |
| | Re: object pipeline? "Mike Blake-Knox" <mikebk@xxxxxx> wrote in message news:VA.000000ba.0ba942ed@xxxxxx Quote: > I've read that one of PowerShell's features is that the pipeline passes > objects. That sounded useful so I tried to use the pipeline to pass an > array. I tested this using an array of strings as the object with a > filter to receive the array. What I found is that PowerShell doesn't > seem to pass the array but instead passes each of values separately. down the pipeline. This is what you want the vast majority of the time. It would bite if I had to do this: $a = 1,2,3,4,5 $a | foreach {$_} | where {$_ % 2} What I'd really like to do is this: $a | where {$_ % 2} And have PowerShell send each element of my array down the pipe. Now if you really want to pass the array or collection down the pipeline without it being unrolled, you can do this: ,$a | foreach {$_} | where {$_ % 2} Note the comma prepended to the array variable. In this scenario, the comma operator will create another array with one element in it - the collection that you don't want to have unrolled. Now when the pipe output mechanism unrolls this new collection (which it only unrolls at the top level) the original collection is emitted as the one and only element which is passed down the pipe as is. BTW the following doesn't work as you might expect: 169# ,$a | where {$_ % 2} Method invocation failed because [System.Object[]] doesn't contain a method named 'op_Modulus'. At line:1 char:18 + ,$a | where {$_ % <<<< 2} -- Keith |
My System Specs![]() |
| | #5 (permalink) |
| | Re: object pipeline? "Keith Hill [MVP]" <r_keith_hill@xxxxxx_no_spam_I> wrote in message news:39E38D48-E47A-4FF5-9126-FE5F36CF34AE@xxxxxx Quote: > BTW the following doesn't work as you might expect: > > 169# ,$a | where {$_ % 2} > Method invocation failed because [System.Object[]] doesn't contain a > method named 'op_Modulus'. > At line:1 char:18 > + ,$a | where {$_ % <<<< 2} -- Keith |
My System Specs![]() |
| | #6 (permalink) |
| | Re: object pipeline? Brandon Shell wrote: Quote: > There are other subtle difference between Function and Filter... > Basically the way I understand it > - Function collects all data in the pipe and processes it' > - Filter is process as you go. named scriptblock. e.g.: function test-pipeline { Begin { # do init stuff here } Process { write-object $_ } End { # do end stuff here } } that's functionally (haha, a pun) equal to: filter test-pipeline { write-object $_ } -- Hal Rottenberg blog: http://halr9000.com powershell category: http://halr9000.com/article/category...ng/powershell/ |
My System Specs![]() |
| | #7 (permalink) |
| | Re: object pipeline? In article <39E38D48-E47A-4FF5-9126-FE5F36CF34AE@xxxxxx>, Keith Hill [MVP] wrote: Quote: > PowerShell unrolls (shreds) collections and sends each individual element* > down the pipeline. Quote: > This is what you want the vast majority of the time. examples show it can be useful. I'd prefer simpler, more consistent operations instead of special cases. How did you learn of this behavior? What should I have read? Thanks again. Mike |
My System Specs![]() |
| | #8 (permalink) |
| | Re: object pipeline? In article <#qSYL7N8HHA.5316@xxxxxx>, Brandon Shell wrote: Quote: > - Function collects all data in the pipe and processes it' > - Filter is process as you go. has generated data. As a result, $_ is "null" which causes various problems. How is one supposed to block untill something has arrived from the pipeline? Should a function/filter test to see if $_ is "null" and if so just return on the expectation that it will be called when data arrives through the pipeline? At one point I thought I had seen something with pseudo functions where one was run when a .ps1 file was read, a second was called when the file was closing and a third was called once for each pipeline object. Thanks Mike |
My System Specs![]() |
| | #9 (permalink) |
| | Re: object pipeline? "Mike Blake-Knox" <mikebk@xxxxxx> wrote in message news:VA.000000bb.111d3e82@xxxxxx Quote: > In article <39E38D48-E47A-4FF5-9126-FE5F36CF34AE@xxxxxx>, Keith > Hill > [MVP] wrote: Quote: >> PowerShell unrolls (shreds) collections and sends each individual element >> down the pipeline. > Thanks! That's exactly what the problem was. > Quote: >> This is what you want the vast majority of the time. > I don't know that I'd want the behaviour but I can certainly see that your > examples show it can be useful. I'd prefer simpler, more consistent > operations instead of special cases. > > How did you learn of this behavior? What should I have read? > recommend "Windows PowerShell in Action" by Bruce Payette. You might also want to check out my blog (http://keithhill.spaces.live.com). I'm working on an Effective PowerShell series of blog posts that you might find useful. -- Keith |
My System Specs![]() |
| | #10 (permalink) |
| | Re: object pipeline? "Mike Blake-Knox" <mikebk@xxxxxx> wrote in message news:VA.000000bc.111d5258@xxxxxx Quote: > In article <#qSYL7N8HHA.5316@xxxxxx>, Brandon Shell > wrote: Quote: >> - Function collects all data in the pipe and processes it' >> - Filter is process as you go. > Apparently the second function/filter can be started before the first > has generated data. As a result, $_ is "null" which causes various > problems. input might be a $null object (value): filter IsNull { Write-Host ($_ -eq $null); $_ } $null | IsNull True functions can also participate in the pipeline but with more flexibility - actually behaving very similar to the way a CMDLET works e.g.: function Sum { begin { Write-Host "begin" $total = 0 } process { Write-Host "processing $_" if ($_) { $total += [int]$_ } } end { Write-Host "end" $total } } 215# 1..5 | Sum begin processing 1 processing 2 processing 3 processing 4 processing 5 end 15 Now this is a lame function (since you could just use Measure-Object -sum) but it illustrates a few things. First, begin does get called before the first object is processed by the function. This gives the filtering function a chance to initialize any state or do other prep work in the begin function. The process function gets called for each object that is received from the pipe. Again, you probably should check for $null here if that does cause problems for you. BTW if it wasn't clear above, $null doesn't mean "no pipeline output" in this context. $null is a legitimate scalar object 1 and "hi". When there are no more objects left in the pipe, then the end function is called to perform any cleanup or in this case output the "folded" result. -- Keith |
My System Specs![]() |
![]() |
| Thread Tools | |
| |
Similar Threads | ||||
| Thread | Forum | |||
| Re: Access object property while passing through pipeline? | PowerShell | |||
| Can I pass object along the pipeline to a ps1? | PowerShell | |||
| Select a random object from pipeline effectively | PowerShell | |||
| WMI Object Win32_Product and Pipeline woes | PowerShell | |||
| Add full (to pipeline) multicasting to tee-object? | PowerShell | |||