2014-03-03 1 views
1

Powershell 버전 : 3.0전달 된 개체의 캐스트를 제거하는 Start-Job cmdlet

안녕하세요 동료 스크립터. 내가 답을 찾을 수없는 문제가 있습니다.

요약 : 작업을 시작할 때 scriptblock 매개 변수는 [System.Collections.Specialized.OrderedDictionary]의 캐스트를 제거하고 [Hashtable]로 바꾸고 있습니다 (즉, 매개 변수를 캐스팅하지 않은 경우). 스크립트 블록). 내 시나리오의 예는 다음과 같습니다 : 그것은 그 객체에 대한 기대했던 것보다 더 속성이있는 객체를 전달하는 것처럼

$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"유형의 개체를 만들 수 없습니다. Param1 속성을 System.Collections.Specialized.OrderedDictionary 개체에 대해 찾을 수 없습니다. 가능한 속성이다 : [COUNT], [isReadOnly의] [키], [값], [IsFixedSize], [SyncRoot], [즉 IsSynchronized]

NOTE 없음 키/값 쌍을 통과하지하면 캐스트가 남아 있고 객체가 스크립트 블록으로 잘 전달됩니다 (매개 변수 목록에 캐스트).

사람 세부 정확한 원인 수 또는 시작 - 작업 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

@ 기호를 사용하여 오타를 지적 해 주셔서 감사합니다. 나는 그것을 메인 포스트에서 업데이트했다. 그러나 스크립트 블록에서 "$ ParamIn"을 "write-host $ ParamIn.GetType()"으로 바꾸는 것처럼 의도 한대로 구현되었는지는 확실하지 않지만 개체가 있음을 알리는 오류를 반환합니다 없는. 그래서 나는 목표물이 의도 한대로 일에 넘겨지고 있다고 생각하지 않는다. 그것에 관한 어떤 생각? –

0

문제는 [System.Collections.Specialized.OrderedDictionary]에 [해시 테이블] 주조의 결과로 나타난다.

이 코드는 유사한 동작을 보여 :

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

난 단지 그것이 당신의 스크립트 블록에 전달되기 전에 시작-작업 cmdlet을 내, 당신의 [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 답장을 보내 주셔서 감사합니다. 솔직히 Dictionary/Hashtable을 주문하기보다는 로그를보고 스크립트에 나열된 것과 비교하면 좋게 일치하는 것이 좋습니다. 나는 기본적으로 순서가 정해진 사전을 포기하고 그냥 객체를 일반 해시 테이블로 변환하고 바로 사전 순으로 구문 분석합니다. –

관련 문제