2017-07-27 183 views
0

我有一個類似於下面的代碼的功能。它接收命令和命令參數。我不得不在後臺運行這個命令並收集輸出。但是,最後的陳述是竊聽我這個錯誤無法將參數綁定到參數「命令」,因爲它爲空。 Powershell

錯誤:

Cannot bind argument to parameter 'Command' because it is null. 
+ CategoryInfo   : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException 
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpre 
ssionCommand 
+ PSComputerName  : localhost 

代碼:

$cmd = 'Get-content' 
$Arg = 'path to file' 
$sb = "$cmd $Arg -ErrorVariable e -ErrorAction Stop" 
invoke-Expression $sb #This printsoutput 
$job = Start-job -ScriptBlock {Invoke-Expression $sb} 
wait-job -id $job.Id 
$job | Receive-job #this should print output but throwing error 

我敢肯定,最後一行是一個投擲的錯誤。

+1

*但我不知道根本原因。*'$ sb'不存在於作業內部。 – PetSerAl

回答

1

這裏的問題是,你實際上並沒有給Invoke-Expression一個命令。

無論何時創建新的上下文(在本例中爲作業),都無法訪問父會話的環境。在你的情況下,$sb目前爲空。

您管理這是通過-ArgumentList參數的Start-Job傳遞值作爲參數的方法:

start-job -ScriptBlock {} -ArgumentList 

爲了便於移交$某人的腳本塊,你這樣做:

$sb = "$cmd $Arg -ErrorVariable e -ErrorAction Stop" 
$job = start-job -ScriptBlock { Param([string]$sb) 
    Invoke-Expression $sb 
} -ArgumentList $sb 

這會引起混亂,所以這是更友好的名稱寫相同的代碼:

$OuterSB = "$cmd $Arg -ErrorVariable e -ErrorAction Stop" 
$job = start-job -ScriptBlock { Param([string]$InnerSB) 
    Invoke-Expression $InnerSB 
} -ArgumentList $OuterSB 
+0

感謝您的詳細解釋。這確實解決了這個問題。 但是,當錯誤來自Invoke-Expression時,爲什麼powershell在最後一行拋出錯誤? –

+0

將'start-job'分配給'$ job'時,您正在將命令放入腳本塊中。這將在後臺啓動該過程。在最後一行,您正在檢索該作業的輸出。您看到的錯誤是該作業的輸出。 –

+0

謝謝,現在它清澈透明。 –

3

$sb置於-argumentlist之外的scriptblock範圍內的另一種替代方法是使用$using:範圍。 (PowerShell 3+)

$cmd = 'Get-content' 
$Arg = 'path to file' 
$sb = "$cmd $Arg -ErrorVariable e -ErrorAction Stop" 
$job = Start-job -ScriptBlock {Invoke-Expression $using:sb} 
wait-job -id $job.Id 
$job | Receive-job 
相關問題