PowerShell

PowerShell| Start-Job の InitializationScript へ引数を複数渡す

More than 1 year has passed since last update.

今回の問題のソースは下記です。

期待通りに動作しないソース

$functions = {
  function Output-Message {
    param (
      [string]$message,
      [string]$name
    )
    sleep 5
    echo "$message : $name"
  }
}

$job = Start-Job -InitializationScript $functions -ScriptBlock {
  param (
    [string]$m,
    [string]$n
  )
  Output-Message $m, $n
} -ArgumentList "Hello World", "kirishima"

# 待機後に結果出力
Wait-Job $job
Write-Host (Receive-Job -Job $job)
Remove-Job $job

Start-Jobはグローバルスコープでも変数を渡せません。ですので、-ArgumentList で引数を渡します。

上記のスクリプトはHello World : kirishimaと出力されてほしいのですが、Hello World kirishima :と出力されます。どうやら、第1引数へ空白区切りで値が代入されているようです。第2引数へ渡す方法は調べた限りありませんでした。
(2017/3/28 追記)ありました、と言うか初心者がつまずく初歩的なミスでした。

解決編

引数を1つしか渡せないので、Hashtable として渡せば今回は問題を解決できそうです。修正版が下記になります。

$functions = {
  function Output-Message {
    param (
      [hashtable]$data                                 # 変更点1
    )
    sleep 5
    $output = $data["message"] + " : " + $data["name"] # 変更点2
    echo $output                                       # 変更点3
  }
}

$job = Start-Job -InitializationScript $functions -ScriptBlock {
  param (
    [string]$m,
    [string]$n
  )
  Output-Message @{message = $m; name = $n} # 変更点4
} -ArgumentList "Hello World", "kirishima"

# 待機後に結果出力
Wait-Job $job
Write-Host (Receive-Job -Job $job)
Remove-Job $job

後から気付きましたが、split で分割する方法もあります。ただ、HashTableで渡したほうが、変数的でわかりやすいので :o: です。

そもそもこちらが正解(2017/3/28 追加)

原因は、Output-Messageを呼び出す際にカンマ区切りで指定していたことでした。Shellであることを忘れてどこぞの言語と勘違いしてました:cry:

$functions = {
  function Output-Message {
    param (
      [string]$message,
      [string]$name
    )
    sleep 5
    echo "$message : $name"
  }
}

$job = Start-Job -InitializationScript $functions -ScriptBlock {
  param (
    [string]$m,
    [string]$n
  )
  Output-Message $m $n # 変更点
} -ArgumentList "Hello World", "kirishima"

# 待機後に結果出力
Wait-Job $job
Write-Host (Receive-Job -Job $job)
Remove-Job $job

参考