开发者

Is scriptblock parameter evaluation different for compiled cmdlets and advanced functions?

In experimenting with scriptblocks, I was attempting to use a scriptblock parameter with an advanced function and noticed that it performs differently than when supplied to a compiled cmdlet.

In reviewing this blog post from the PowerShell Team blog, it appears that the PowerShell engine should be evaluating the scriptblock if a scriptblock is not a valid input for the parameter. It seems that when calling the function with a scriptblock parameter, it attempts to convert a scriptblock to the parameters type directly, rather than evaluating the scriptblock based on the current object in the pipeline.

My intention is to duplicate behavior like:

Import-CSV somecsv.csv | get-wmiobject -class {$_.class} -Computer {$_.computer}

for advanced functions.

Example script:

$sb = {throw "If there was an error, the scriptblock was evaluated!"}

function test ()
{
  param (
    [Parameter()]
    [string]
    $ThisShouldBeEvaluatedForEachItem,
    [Parameter(ValueFromPipelineByPropertyName = $true)]
    [string]
    $FullName
 )  

 process 
 {  
  write-host $Fullname, $ThisShouldBeEvaluatedForEachItem
 }
} 
Get-ChildItem | test -ThisShouldBeEvaluatedForEachItem $sb

Is this the intended behavior or am I headed i开发者_JS百科n the wrong direction?

Based on Keith's response, I added ValueFromPipeline and ValueFromPipelineByPropertyName (in two separate tests) to the Parameter attribute for the ThisShouldBeEvaluatedForEachItem parameter. Doing that makes the example work, though it seems to defeat the stated purpose of scriptblock parameters from the Team Blog post.


If the parameter is ValueFromPipeline or ValueFromPipelineByPropertyName then PowerShell will evaluate the Scriptblock and try to coerce the result to the parameter type. We got this info from the PowerShell team a while back:

ScriptBlock arguments are passed as is (as a ScriptBlock) when the parameter type is Object, ScriptBlock, or a type deriving from ScriptBlock, or collections of these types.

We only invoke the ScriptBlock argument during parameter binding when there is pipeline input and there was no trivial way to bind the ScriptBlock directly.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜