5

Invoke-Command在脚本块采用字典类型参数的情况下,我一直在运行错误:

无法处理参数“字典”上的参数转换。无法将“System.Collections.Hashtable”类型的“System.Collections.Hashtable”值转换为“System.Collections.Generic.IDictionary`2[System.String,System.String]”类型。在 line:7 char:1 + Invoke-Command -ComputerName 。-ArgumentList $dictionary -ScriptBlock ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidData: (:) [], ParameterBindin...mationException + FullyQualifiedErrorId : ParameterArgumentTransformationError + PSComputerName:本地主机

经过大量挖掘,我能够将脚本简化为下面的 MVP 以显示此问题的根源:

[System.Collections.Generic.IDictionary[string, string]]$dictionary = New-Object -TypeName 'System.Collections.Generic.Dictionary[string, string]' 
$dictionary.Add('one', 'hello')
$dictionary.Add('two', 'world')
Write-Verbose "Main Script $($dictionary.GetType().FullName)" -Verbose #outputs: VERBOSE: Before System.Collections.Generic.Dictionary`2[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]
Invoke-Command -ComputerName . -ArgumentList $dictionary -ScriptBlock {
    Param (
        #[System.Collections.Generic.IDictionary[string, string]] #if I leave this in I get a conversion error
        $dictionary
    )
    Write-Verbose "Function before $($dictionary.GetType().FullName)" -Verbose #outputs: VERBOSE: After System.Collections.Hashtable
    function Poc {} #this line seems to cause the `$dictionary` to become a HashTable
    Write-Verbose "Function after $($dictionary.GetType().FullName)" -Verbose #outputs: VERBOSE: After System.Collections.Hashtable

}

似乎如果脚本块Invoke-Command包含任何内联函数,则参数会自动转换为HashTable; 而如果脚本块不包含任何嵌套函数定义,则参数保留为System.Collections.Generic.IDictionary[string, string].

我是否在滥用此功能/是否有常见的解决方法?或者这只是 PowerShell 中的一个错误?

4

1 回答 1

5

不幸的是,从 PowerShell Core 7.0.0-preview.2 开始,这是 PowerShell 远程处理(这是基于)的反序列化代码的一个已知问题:Invoke-Command -ComputerName

在反序列化时,任何实现IDictionary接口的对象都被错误地假定为始终是常规的、非泛型的[hashtable][1]并被反序列化。

当原始对象是有序字典[2]时,这尤其成问题,因为键的顺序丢失了,索引到它们的能力也丢失了。

请参阅GitHub 问题 #2861,它被标记为“待命”,这意味着社区可以免费提供解决问题的 PR。


[1] System.Collections.Hashtable,可在 PowerShell 中使用@{ ... }文字创建,其中键和值都是[object]-typed。

[2] 例如,System.Collections.Specialized.OrderedDictionary,可在 PowerShell 中使用[ordered] @{ ... }文字创建,也可使用[object]-typed 键和值(非泛型);令人惊讶的是,在撰写本文时,没有通用的有序字典类型 - 请参阅此问题

于 2019-08-20T11:54:04.143 回答