20

スクリプトブロックを実行するバックグラウンドジョブを作成しようとしています。このスクリプトブロックをパラメーターとして渡す必要がありますが、構文を機能させることができないようです。スクリプトブロックは途中で文字列に変換されています。

スクリプトブロックをローカル関数に渡すと正常に機能しますが、start-jobでは機能しません

次の構文が機能します。

function LocalFunction
{
    param (
        [parameter(Mandatory=$true)]
        [ScriptBlock]$ScriptBlock
    )

    &$ScriptBlock | % { echo "got $_" }
}

LocalFunction -ScriptBlock { echo "hello" }

これにより、期待どおりに「gothello」が出力されます。

しかし、以下は失敗します:

$job = start-job -argumentlist { echo "hello" } -scriptblock {
    param (
        [parameter(Mandatory=$true)]
        [ScriptBlock]$ScriptBlock
    )
    &$ScriptBlock | % { echo "got $_" }
}
start-sleep -s 1
receive-job $job

返されるエラーは

Receive-Job : Cannot process argument transformation on parameter 'ScriptBlock'. Cannot convert the " echo "hello" " value of type "System.String" to type "System.Management.Automation.ScriptBlock".

したがって、エラーを正しく読んでいると、-argumentlistが何らかの形で引数を文字列に強制しているように見えます。

この構文を機能させる方法を知っているPowerShellの達人はいますか?

前もって感謝します、

ベン

4

5 に答える 5

20

これを解決する方法の 1 つは、スクリプト ブロック コードを文字列として渡し、ジョブ内の文字列からスクリプト ブロックを作成して実行することです。

Start-Job -ArgumentList "write-host hello"  -scriptblock {

    param (
        [parameter(Mandatory=$true)][string]$ScriptBlock
    )

    & ([scriptblock]::Create($ScriptBlock))

} | Wait-Job | Receive-Job
于 2012-08-07T11:29:24.290 に答える
4

私の実験に基づいて、スクリプト ブロックを渡した場合でも、PowerShell は Object[] である -ArgumentList を文字列として解析しています。次のコード:

$job = start-job -scriptblock { $args[0].GetType().FullName } -argumentlist { echo "hello" }
start-sleep -s 1
receive-job $job

次の出力が得られます。

System.String

私の知る限り、ここでの唯一の解決策は Shay のものですが、この場合、PowerShell はスクリプト ブロックを文字列として解析するため、-ArgumentList を文字列として渡す必要はありません。

于 2012-09-03T18:12:13.230 に答える
1

文字列として読み込んでから、スクリプトブロックに変換する必要があります。

powershell v1 では、これを行うことができます。

$ScriptBlock = $executioncontext.invokecommand.NewScriptBlock($string)

そしてpowershell v2では、これを行うことができます:

$ScriptBlock = [scriptblock]::Create($string)

したがって、コードは次のようになります。

function LocalFunction
{
    param (
        [parameter(Mandatory=$true)]
        $ScriptBlock
    )

    $sb = [scriptblock]::Create($ScriptBlock)

    $sb | % { echo "got $_" }
}

LocalFunction -ScriptBlock "echo 'hello'"

'[scriptblock]::Create($ScriptBlock)' は、スクリプト ブロックを作成するために、文字列を中かっこで囲みます。

ここで情報を見つけましたhttp://get-powershell.com/post/2008/12/15/ConvertTo-ScriptBlock.aspx

于 2013-03-26T19:08:18.740 に答える