$MindWarpingPower = $Cmdlets + $ScriptBlock_Parameters

A while ago I blogged about the power of Flexible Pipeling Scriptblock parameters.  The mechanics of this are quite simple:  In a pipeline environment, if you provide a SCRIPTBLOCK to a parameter which does not take a SCRIPTBLOCK or an OBJECT, the PowerShell engine assigns the current pipeline object to the variable "$_", runs the scriptblock and uses whatever value it returns for the value of that parameter. 


Looking back at this, I don’t think we’ve done a good enough job explaining it or promulgating its use because it is incredibly powerful and I just don’t see it being used enough.  Let me give a couple of simple examples of how I used it this morning.  It is a technique that is well worth learning because you can do MIND-WARPING things once you figure out how to leverage it’s power.


This morning I wanted to email a set of PS1 files to someone.  Exchange blocks PS1 files so what I do is to rename these by added ".txt" to them.  I’ve see number of people sharing scripts that do something similar using the following technique:


foreach ($file in dir *.ps1) {
    $newName = $file.Name + ".TXT"
    copy-item -Path $file.Name -Destination $newName


That works but heavens, why do all that when you could just use ScriptBlock Parameters?  Now when you start using scriptblocks, you might what to leverage our friend -WHATIF until you are comfortable with how it works (isn’t -WHATIF da bomb?).

Dir *.ps1 | Copy-Item -Destination {$_.Name + ".TXT"} -Whatif


On the way back, you can do this:

Dir *.ps1.txt |Rename-item -NewName {$_.Name -replace ".txt"} -whatif


Now the scriptblock can be as large as you like you can do anything you want in it so feel free to get creative.  Imagine that you wanted to normalize/serialize the names of a set of scripts.  You could do it this way:

$Global:x=0; dir *.ps1 |copy-Item -Destination {"ScriptFile{0:000}" -f $global:x++} -whatif

Here is an fun one:

dir *.ps1 |copy-Item -Destination {if ($_.length -ge 100) {$_.Name + ".BIG"} else {$_.Name + ".SMALL"}} -whatif


Experiment and Enjoy!

Jeffrey Snover [MSFT]
Windows Management Partner 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