When you are doing a little advanced scripting and passing scriptblocks around, one of the problems I encountered was how to execute the scriptblock in a pipeline and get the value out of it. Say you want the user to be able to enter a scriptblock and compare your data to the value returned from it – how is that done?
Executing a scriptblock is easy using the &-operator
You can also use the invoke method -
If you want to have a filtering scriptblock e.g. comparing a value with a scriptblock (not its value), I found it easy and logical to use where(-object) -
$sb={$_.name –like ‘note*’}
dir $env:windir | where $sb
# or
if (dir $env:windir | where $sb) {"Slipped through filter, go on"}
But what if you want to execute it, feeding in values from the pipeline to get new values? (Often you would only send in one value at a time). The answer is foreach(-object) -
$sb={$_.name.toupper()}
dir $env:windir note* | foreach $sb
When can this be useful? In numerous places, I would say. What if you have some getter script, with these arguments -
Get-XXX –dateproperty <property>
–value <value|scriptblock>
–filter <scriptblock>
If this case the code is something like (pseudo code) -
get-object | where &$filter| foreach {
if ($value –is [scriptblock]) {
$compareto=$_ | foreach $value
else {
$compareto=$value
}
if ($_.$dateproperty –gt $value) {
“ok”
}
}
The user can then either stick it a value or calculate a value using the scriptblock – and that based on the data from the object itself and before the comparison is made -
# Getting files accessed after January 1st
get-xxx–dateproperty lastAccessTime –value ([datetime] "2009-01-01")
# Getting files accessed 90 days after it was modified
get-xxx–dateproperty lastaccesstime –value {$_.lastwritetime.adddays(90)}
The latter example was not possible without parsing a scriptblock.