Windows Vista Forums
Vista Forums Home Join Vista Forums Donate Vista Tutorials Tags

Welcome to Vista Forums we are your forum to discuss Windows Vista x64 and x86 systems. Whether you need help or just want to post an idea you have on Vista, this is the forum for you.
Register at Vista forums...the world biggest Windows Vista resource Join Vista Forums Now

Go Back   Vista Forums > Microsoft Technical Newsgroups > PowerShell

Pipeline and ScriptBlocks

Update your Vista Drivers Update Your Drivers Now!!
Closed Thread
 
Thread Tools Display Modes
Old 01-11-2008   #1 (permalink)
Shane
Guest


 

Pipeline and ScriptBlocks

ok, here is the script.

$items="Item"
$act={ # Type in a PowerShell script here

% { Update-Item -ItemDataRow $_ }
}
$items | foreach { Get-Items $_ } | &$act

Now some details about the Cmdlets here. The Get-Items cmdlet outputs
DataRow objects. The Update-Item parameter of -ItemDataRow accepts DataRow
objects from the pipeline. For some reason, the following is showed when
this script is run.

Update-Item : The argument cannot be null or empty.
At line:2 char:37
+ % { Update-Item -ItemDataRow <<<< $_ }

Now the kicker. This next script runs fine but is, from what I understand,
the same operation.

$items="Item"

$items | foreach { Get-Items $_ } | % { Update-Item -ItemDataRow $_ }

Is this suppose to happen or am I doing something wrong? I am totally
stumped on this one. Any help would be awesome.

Shane

My System SpecsSystem Spec
Old 01-11-2008   #2 (permalink)
Jeff
Guest


 

Re: Pipeline and ScriptBlocks

On Jan 11, 3:11 pm, Shane <Sh...@xxxxxx> wrote:
Quote:

> ok, here is the script.
>
> $items="Item"
> $act={ # Type in a PowerShell script here
>
> % { Update-Item -ItemDataRow $_ }
> }
> $items | foreach { Get-Items $_ } | &$act
>
> Now some details about the Cmdlets here. The Get-Items cmdlet outputs
> DataRow objects. The Update-Item parameter of -ItemDataRow accepts DataRow
> objects from the pipeline. For some reason, the following is showed when
> this script is run.
>
> Update-Item : The argument cannot be null or empty.
> At line:2 char:37
> + % { Update-Item -ItemDataRow <<<< $_ }
>
> Now the kicker. This next script runs fine but is, from what I understand,
> the same operation.
>
> $items="Item"
>
> $items | foreach { Get-Items $_ } | % { Update-Item -ItemDataRow $_ }
>
> Is this suppose to happen or am I doing something wrong? I am totally
> stumped on this one. Any help would be awesome.
>
> Shane
Shane,

I don't think you can execute a script block in the middle of a
pipeline like that. You may need to do something more like this:

$act = { # Type in a PowerShell script here
Update-Item -ItemDataRow $item
}

foreach ( $item in ( $items | foreach { Get-Items $_ } ) )
{
&$act
}

Good luck.

Jeff
My System SpecsSystem Spec
Old 01-11-2008   #3 (permalink)
Tao Ma
Guest


 

Re: Pipeline and ScriptBlocks

Invoking a blockscript in pipeline have to use "$input" to access items on
the pipeline. It's different from using "$_", because PowerShell have to
accumulate all of stuff before it can pass them to the blockscript.

Maybe you can use filter to solve this problem:

filter proc { "Access item on the pipeline using $_" }


Best wishes!

Tao Ma

"Shane" <Shane@xxxxxx> дʼ
news:FCC7822C-69A2-483F-A868-3EA90944C622@xxxxxx
Quote:

> ok, here is the script.
>
> $items="Item"
> $act={ # Type in a PowerShell script here
>
> % { Update-Item -ItemDataRow $_ }
> }
> $items | foreach { Get-Items $_ } | &$act
>
> Now some details about the Cmdlets here. The Get-Items cmdlet outputs
> DataRow objects. The Update-Item parameter of -ItemDataRow accepts
DataRow
Quote:

> objects from the pipeline. For some reason, the following is showed when
> this script is run.
>
> Update-Item : The argument cannot be null or empty.
> At line:2 char:37
> + % { Update-Item -ItemDataRow <<<< $_ }
>
> Now the kicker. This next script runs fine but is, from what I
understand,
Quote:

> the same operation.
>
> $items="Item"
>
> $items | foreach { Get-Items $_ } | % { Update-Item -ItemDataRow $_ }
>
> Is this suppose to happen or am I doing something wrong? I am totally
> stumped on this one. Any help would be awesome.
>
> Shane

My System SpecsSystem Spec
Old 01-11-2008   #4 (permalink)
Shane
Guest


 

Re: Pipeline and ScriptBlocks

Genius! $input was what I was missing. Thanks Tao.

Shane

"Tao Ma" wrote:
Quote:

> Invoking a blockscript in pipeline have to use "$input" to access items on
> the pipeline. It's different from using "$_", because PowerShell have to
> accumulate all of stuff before it can pass them to the blockscript.
>
> Maybe you can use filter to solve this problem:
>
> filter proc { "Access item on the pipeline using $_" }
>
>
> Best wishes!
>
> Tao Ma
>
> "Shane" <Shane@xxxxxx> дÈëÓʼþ
> news:FCC7822C-69A2-483F-A868-3EA90944C622@xxxxxx
Quote:

> > ok, here is the script.
> >
> > $items="Item"
> > $act={ # Type in a PowerShell script here
> >
> > % { Update-Item -ItemDataRow $_ }
> > }
> > $items | foreach { Get-Items $_ } | &$act
> >
> > Now some details about the Cmdlets here. The Get-Items cmdlet outputs
> > DataRow objects. The Update-Item parameter of -ItemDataRow accepts
> DataRow
Quote:

> > objects from the pipeline. For some reason, the following is showed when
> > this script is run.
> >
> > Update-Item : The argument cannot be null or empty.
> > At line:2 char:37
> > + % { Update-Item -ItemDataRow <<<< $_ }
> >
> > Now the kicker. This next script runs fine but is, from what I
> understand,
Quote:

> > the same operation.
> >
> > $items="Item"
> >
> > $items | foreach { Get-Items $_ } | % { Update-Item -ItemDataRow $_ }
> >
> > Is this suppose to happen or am I doing something wrong? I am totally
> > stumped on this one. Any help would be awesome.
> >
> > Shane
>
>
>
My System SpecsSystem Spec
Old 01-11-2008   #5 (permalink)
Shane
Guest


 

Re: Pipeline and ScriptBlocks

Just to wrap this up, the solution was the following.

$items="Item"
$act={
$input | % { Update-Item -ItemDataRow $_ }
}
$items | foreach { Get-Items $_ } | &$act

Shane

"Tao Ma" wrote:
Quote:

> Invoking a blockscript in pipeline have to use "$input" to access items on
> the pipeline. It's different from using "$_", because PowerShell have to
> accumulate all of stuff before it can pass them to the blockscript.
>
> Maybe you can use filter to solve this problem:
>
> filter proc { "Access item on the pipeline using $_" }
>
>
> Best wishes!
>
> Tao Ma
>
> "Shane" <Shane@xxxxxx> дÈëÓʼþ
> news:FCC7822C-69A2-483F-A868-3EA90944C622@xxxxxx
Quote:

> > ok, here is the script.
> >
> > $items="Item"
> > $act={ # Type in a PowerShell script here
> >
> > % { Update-Item -ItemDataRow $_ }
> > }
> > $items | foreach { Get-Items $_ } | &$act
> >
> > Now some details about the Cmdlets here. The Get-Items cmdlet outputs
> > DataRow objects. The Update-Item parameter of -ItemDataRow accepts
> DataRow
Quote:

> > objects from the pipeline. For some reason, the following is showed when
> > this script is run.
> >
> > Update-Item : The argument cannot be null or empty.
> > At line:2 char:37
> > + % { Update-Item -ItemDataRow <<<< $_ }
> >
> > Now the kicker. This next script runs fine but is, from what I
> understand,
Quote:

> > the same operation.
> >
> > $items="Item"
> >
> > $items | foreach { Get-Items $_ } | % { Update-Item -ItemDataRow $_ }
> >
> > Is this suppose to happen or am I doing something wrong? I am totally
> > stumped on this one. Any help would be awesome.
> >
> > Shane
>
>
>
My System SpecsSystem Spec
Old 01-11-2008   #6 (permalink)
Karl Prosser[MVP]
Guest


 

Re: Pipeline and ScriptBlocks

you can use scriptblocks in the pipeline..

if your scriptblock is acting like a function that processes everything
at once , you just use $input , .. if you put it in a process block,
then its more pipeline friendly and you can use $_

an example of the former

1..5 | &{ $input.length ; $input + "yo" }

and of the later

1..5 | &{ process { "HELLO $_ "} }


the above scriptblock with the process block inside it , is akin to the
normal use of the foreach-object cmdlet..

in fact the foreach-object cmdlet, when you providing ONE argument is
akin to this function (less error catching)

function myforeach-object ([scriptblock]$process)
{
process { &$process }
}

1..5 | myforeach-object { "hello $_" }

and if you use foreach-object with begin, process and end sections then
its more like this function

function myforeach-object2
([scriptblock]$process,[scriptblock]$begin,[scriptblock]$end)
{
begin { if ($begin -ne $null) {&$begin } }
process { &$process }
end { if ($end -ne $null) {&$end } }
}

see its very simple.. the functionality really is the functionality of
1) a scriptblock, and 2) The design of the pipeline.. foreach-object
really is just a user friendly wrapping on that, more of a best practice
put into an example

a function and a filter as well are simple scriptblocks.. the filter
automatically it putting it in a process block.. but both essential are
scriptblocks with a name and some metadata, and just a convenient syntax
that doesn't look so alien to somebody from another language.

-Karl



My System SpecsSystem Spec
Old 01-11-2008   #7 (permalink)
Shane
Guest


 

Re: Pipeline and ScriptBlocks

Thanks for the detailed post. I think I understand most of what you are
saying. I am still a bit confused on why certain things don't work as I
would expect. Here is what I started with in this quest.

$items="Org Unit 5004"

$items | foreach { Get-FPOrgUnits $_ } | Update-FPOrgUnitVersion -OrgUnit $_
ERROR: Update-FPOrgUnitVersion : The argument cannot be null or empty.
ERROR: At line:1 char:74
ERROR: + $items | foreach { Get-FPOrgUnits $_ } | Update-FPOrgUnitVersion
-OrgUnit <<<< $_


I thought the $_ was suppose to represent a single object in the pipeline
which in the above case should be the DataRow output by Get-FPOrgUnits,
correct?

Thanks a bunch
Shane

My System SpecsSystem Spec
Old 01-12-2008   #8 (permalink)
Karl Prosser[MVP]
Guest


 

Re: Pipeline and ScriptBlocks

> $items="Org Unit 5004"
Quote:

>
> $items | foreach { Get-FPOrgUnits $_ } | Update-FPOrgUnitVersion -OrgUnit $_
This is a common complaint.. however there is no $_ in that line.. $_ is
coming through the pipeline.. so you would reference $_ inside whatever
scriptblock that is processing things. (the update-FPorgUnitVersion
itself.. if it was designed to take in lots of information..

put it this way.. $_ is an item that is for each item coming through the
pipeline so

1..3 | will have 3 different $_

however a cmdlet or function call and thus parameters on it. is only
invoked ONCE there... even though internally it can process each item.. i.e

function Update-FPorgUnitVersion
{
process { $_ }
}

or if you need to call the updatefporgunitversion each time then you'd
use foreach

$items | foreach { Get-FPOrgUnits $_ } | foreach-object {
Update-FPOrgUnitVersion -OrgUnit $_ }

-Karl

My System SpecsSystem Spec
Old 01-21-2008   #9 (permalink)
Keith Hill [MVP]
Guest


 

Re: Pipeline and ScriptBlocks

"Karl Prosser[MVP]" <karl@xxxxxx_o_w_e_r_s_h_e_l_l.com> wrote in message
news:Ou##3wJVIHA.5360@xxxxxx
Quote:

> you can use scriptblocks in the pipeline..
>
> if your scriptblock is acting like a function that processes everything at
> once , you just use $input , .. if you put it in a process block, then its
> more pipeline friendly and you can use $_
>
> an example of the former
>
> 1..5 | &{ $input.length ; $input + "yo" }
Hmm, in this case $input is a System.Array+SZArrayEnumerator which doesn’t
have a length property. I guess the important point here is that $input
collects all input in an enumerator (IEnumerator) instead of an array. So
you have to be careful how you access it. Foreach works nicely:

21> 1..5 | &{ foreach ($i in $input) { "HELO $i" }}
HELO 1
HELO 2
HELO 3
HELO 4
HELO 5

Indexing:

22> 1..5 | &{ $input[1]}
Unable to index into an object of type System.Array+SZArrayEnumerator.
At line:1 char:18
+ 1..5 | &{ $input[1 <<<< ]}

- not so much. :-)

--
Keith

My System SpecsSystem Spec
Closed Thread

Thread Tools
Display Modes



Similar Threads
Thread Thread Starter Forum Replies Last Post
[v1]break inside scriptblocks and in the pipeline Karl Prosser[MVP] PowerShell 11 11-14-2007 02:29 PM
Using the $_ pipeline with WMI Larry R PowerShell 2 04-27-2007 09:27 AM
pipeline timeout William Stacey [C# MVP] PowerShell 0 04-09-2007 03:26 PM
A pipeline exercise Roman Kuzmin PowerShell 5 10-19-2006 10:56 AM
running scriptblocks without Foreach-Object cmdlet? dreeschkind PowerShell 4 06-23-2006 02:12 AM


Vistax64.com is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
Designer Media 2005-2008

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51