情報を探すのに苦労したので、ココにメモ。
概要
Start-Processで$MyInvocationを使用しているスクリプトを実行すると、$MyInvocationがnullになる。
スクリプトを実行 & 戻り値取得 & 実行スクリプト内でスクリプト自身のパス取得、をやろうとするとハマる。
Power Shell v3.0で確認。参照元情報ではPower Shell v2.0で確認。
発生例
Script2.ps1はスクリプトのパス取得に$MyInvocationを使用しており、Script1.ps1からScript2.ps1をStart-Jobで実行する。
Script1.ps1
function PSScriptRoot { $MyInvocation.ScriptName | Split-Path }
 	
$job = Start-Job -FilePath "$(PSScriptRoot)\Script2.ps1"
$job | Wait-Job | Receive-Job
Script2.ps1
function PSScriptRoot { $MyInvocation.ScriptName | Split-Path }
Trap { throw $_ }
"Invoking Script2.ps1"
Script1.ps1を実行すると、エラーになる。
Receive-Job : Cannot bind argument to parameter 'Path' because it is an empty string.
At C:\dev\Script1.ps1:4 char:30
+ $job | Wait-Job | Receive-Job <<<<
    + CategoryInfo          : InvalidData: (:String) [Split-Path], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyStringNotAllowed,Microsoft.PowerShell.Commands.SplitPathCommand
Script2.ps1の$MyInvocation.ScriptNameがnullになっている。
スコープがはずれてしまう。
対処法
ScriptBlockを作成した上で呼び出す。
分かりやすくと
$script2 = "$(PSScriptRoot)\Script2.ps1"
$scriptBlock = [ScriptBlock]::Create($script2)
$job = Start-Job -ScriptBlock $scriptBlock
$job | Wait-Job | Receive-Job
実際はこんな感じで
$job = Start-Job -ScriptBlock ([ScriptBlock]::Create("$(PSScriptRoot)\Script2.ps1"))
$job | Wait-Job | Receive-Job
・・・こんなの絶対わかんねぇよ(;´Д`)