An Administrator's guide to PowerShell

Thursday, January 4, 2007

The Beginning and the End (the process to)

In my powershell journeys I have found a huge quantity of glorious abilities wrapped up in this truly POWER shell. One of these superpowers is the concept of filter/function processing. While I do not consider myself a guru in any stretch I have done a good bit of work with functions and think I have a sound grasp of this ability.

I haven't used filters that much so I will stick with what I know... functions. Oh... glorious functions! These have been the life blood of my powershell experience. I came from a VBScript back ground and have always been super anal (or lazy) about code reuse. I would always try to black box my code to be able to reuse later. While this is a good practice IMHO... it does tend to get lost sometimes... This is where I believe Powershell functions come in.

There a ton of things you can do with functions and I don't have time to discuss them all, so I am going to focus on my favorite.... Begin, Process, and End oh my!

Lets start with the basic layout of a function:
---------------------------------------------
function foo{
write-host "Hello World"
}


Ok... nothing spectacular there, but what if I want to be more specific to whom I say hello

function foo{
param([string]$name)
Write-Host "Hello $name"
}


This is nice... but still... nothing big going on. I mean seriously... what kinda scripting language cant take parameters.


function foo{
Param([string]$name)
Begin{
# Only gets process at the Beginning
# Normally include Variable creation and functions
Write-Host "Starting"
}
Process{
# Gets process for each object in the pipe (if ones exist)
if($_){Write-Host "Hello $_"}
}
End{
# Always get processed once at the end
if($name){Write-Host "Hello $name"}
}
}


Now... as trivial as this looks... this function is truly amazing. It not only has the ability to take a parameter, but it can also take a pipe (pipe is explained below.)

Like I said... functions of lots of abilities... but this is my favorite. Thanks to Jeffrey and the Team.... GREAT IDEA!!!


===============================================
pipe: A pipe is when you get the results of one command and pipe them to another... Kinda like you did in DOS or BASH, but instead of pass text... in powershell you pass objects (mostly arrays of strings.)

4 comments:

Jeffrey Snover said...

Congratulations on starting the blog! I'll be a reader. I can't overstate how useful blog entries like the one above it. Finding out what you find useful about PowerShell helps us to prioritize scenarios which affects what we'll deliver in our next release. The only thing more useful is when you tell us about something that you find painful to do or that you can't do.

Cheers!

Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

Adrian Milliner said...

What I find interesting is that functions and filters behave differently in some cases, but not others.

A function with begin/process/end is effectively a filter (so long as it processes $_), but a function without begin/process/end is not.

For example, If you want to have a function operate as a pipeline filter, then you can simply use filter and not have to use the process block:

For example, these two are functionally the same:

function foo {
process {
echo ">> $_"
}
}

and

filter bar { echo ">> $_" }

ls | foo
ls | bar

do the same. The filter version is a lot easier to read though.

If seems to me, therefore, that "filter x {xxx}" is just syntactic sugar for "function x {process{xxx}}"

Of course, if you forget the process block, and you wanted to be really perverse, you can mix these up styles, eg:

function odd { echo ">> $_" }
ls | %{odd}

jv said...

Excellent start B.S. I had forgoten the syntax of teh function/pipe support. This blog was there by coincidence ( from Snover ) so I referenced it over a t ScriptingAnswers.com. Thought your explanation was just right for scripters and others.

Hey - we're neighbors -

Anonymous said...

...usually arrays of strings

I wouldn't say that. If you use most standard powershell commands, you'll get actual objects which can be inspected, etc.

A good guideline to follow in fact would be to always try to return objects (rather than just strings) in your functions. This will allow better code reuse as consumers will be able to do more things with the result.

About Me

Montclair, NJ, United States

technorati

Add to Technorati Favorites