2014-03-03 82 views
1

Powershell版本:3.0開始作業cmdlet刪除通過的對象鑄造

你好同事scripters。我有一個問題,我似乎無法找到答案。

摘要: 嘗試開始作業時,scriptblock參數正在移除[System.Collections.Specialized.OrderedDictionary]的轉換並將其替換爲[Hashtable](即如果我沒有將參數scriptblock)。我的方案的下面是一個例子:

$Job = Start-Job -ScriptBlock { 
param(
    [System.Collections.Specialized.OrderedDictionary]$Params = $(throw "Please pass Params.") 
) 
} -Name "Execute" -ErrorVariable Errors -ErrorAction Stop -ArgumentList $Params 

當嘗試一個OrderedDictionary對象傳遞到與它鍵/值對的工作,它就像它傳遞一個對象,具有更多的屬性比它期待該對象類型:

$Params = [ordered]@{ "Param1" = "Value1"; "Param2" = "Value2" } 

我使用以下行來執行我的工作:

$ret = Receive-Job $job -Wait -AutoRemoveJob 

結果:

錯誤:無法處理參數'Params'的參數轉換。無法創建「System.Collections.Specialized.OrderedDictionary」類型的對象。未找到System.Collections.Specialized.OrderedDictionary對象的Param1屬性。 可用屬性是: [COUNT],[IsReadOnly],[鍵],[值],[IsFixedSize],[SyncRoot上],[IsSynchronized]

注意:當通過無鍵/值對,所述轉換仍然保留,並且對象傳遞到scriptblock就好了(在參數列表中轉換)。

任何人都可以詳細說明確切原因或開始作業cmdlet正在做什麼?我只是使用錯了嗎?這個對象類型是否在作業中不可用?是因爲它是一個系統對象嗎?

回答

0

在Start-Job中使用腳本塊似乎對我來說很奇怪。我不知道你爲什麼這樣做,但是你用它給出的例子看起來應該有一個更好的方法來做到這一點。
我不認爲你的問題與你的OrderedDictionary的構建相關。把工作從它中解放出來,然後嘗試按照現在的方式製作這個對象,並引發錯誤。

至少您需要在[Ordered]之後插入@符號。

既然你似乎需要一些參數和所有的,如果是我我會從它的$ret =線移動到一個函數,然後調用該函數是這樣的:

$Params = [ordered]@{ "Param1" = "Value1"; "Param2" = "Value2" } 
Function Quibble { 
param(
    [System.Collections.Specialized.OrderedDictionary]$ParamIn = $(throw "Please pass Params.") 
) 
Start-Job -ScriptBlock {$ParamIn} -Name "Execute" -ErrorVariable Errors -ErrorAction Stop -ArgumentList $ParamIn 
} 
$ret = Receive-Job $(Quibble $Params) -Wait -AutoRemoveJob 

此分析沒有錯誤在我的最後,儘管我沒有真正將實際的工作數據傳遞給它,它基本上什麼都沒做。很明顯,如果沒有其他更改我隨機提出的愚蠢函數名稱,您將需要修改它以滿足您的需求。

+0

感謝@TheMadTechnician用@符號指出錯字。我已在主帖中更新過。然而,我不確定你所說的實現是否按照預期工作,就好像你在腳本塊中用「write-host $ ParamIn.GetType()」替換了「$ ParamIn」,它返回一個錯誤,指出對象是空值。所以我不認爲這個對象是按照預期被傳遞到工作中的。對此有何想法? –

0

該問題似乎是將[散列表]轉換爲[System.Collections.Specialized.OrderedDictionary]的結果。

此代碼顯示出類似的行爲:

$hashTable = @{ "Param1" = "Value1"; "Param2" = "Value2" } 
[System.Collections.Specialized.OrderedDictionary]$dictionary = $hashTable 

我只能推測,啓動作業命令內,你的[OrderedDictionary]被強制轉換回[哈希表]它被傳遞給你的腳本塊之前。

無序字典會爲你工作嗎?使用[IDictionary]界面的工作原理:

$Dictionary = [ordered]@{ "Param1" = "Value1"; "Param2" = "Value2" } 

$job = Start-Job -Name "Execute" -ArgumentList $Dictionary -ScriptBlock { 
    param 
    (
     <# 
     Using this interface type gives the following error: 
      Cannot process argument transformation on parameter 'Params'. 
      Cannot convert the "System.Collections.Hashtable" value of type "System.Collections.Hashtable" to type "System.Collections.Specialized.IOrderedDictionary". 

     This would indicate that Start-Job is likely casting the [OrderedDictionary] back to a [hashtable]. 

     [System.Collections.Specialized.IOrderedDictionary] 
     $Params = $(throw "Please pass Params.") 
     #> 

     # This type works but is unordered. 
     [System.Collections.IDictionary] 
     $Params = $(throw "Please pass Params.") 
    ) 

    # Just to prove the params are passed in. 
    $Params | Out-String | Write-Host -ForegroundColor Green 
} 

$ret = Receive-Job $job -Wait -AutoRemoveJob 
+0

感謝您的回覆@skataben。老實說,它比字典/散列表的要求更有優先性(因此當人們查看日誌並與腳本中列出的內容進行比較時,它們很好地匹配)。我已經基本放棄它作爲一個有序的字典,只是將對象轉換爲一個正常的哈希表,現在就按字母順序解析它。 –