Azure PowerShell 5.1.1操作Azure存储表时遇类型转换错误求助
我之前也碰到过这个一模一样的诡异问题!当用PowerShell尝试往Azure存储表里插入或合并实体时,突然弹出了一个看起来完全矛盾的类型转换错误——明明都是Microsoft.WindowsAzure.Storage.Table.TableOperation类型,却提示无法转换。
问题重现
当时运行的脚本片段是这样的:
$entity = New-Object "Microsoft.WindowsAzure.Storage.Table.DynamicTableEntity,$assemblySN" -ArgumentList $PartitionKey, $RowKey $result = $table.CloudTable.Execute([Microsoft.WindowsAzure.Storage.Table.TableOperation]::InsertOrMerge($entity))
随即收到的错误信息:
Cannot convert argument "operation", with value: "Microsoft.WindowsAzure.Storage.Table.TableOperation", for "Execute" to type "Microsoft.WindowsAzure.Storage.Table.TableOperation": "Cannot convert the "Microsoft.WindowsAzure.Storage.Table.TableOperation" value of type "Microsoft.WindowsAzure.Storage.Table.TableOperation" to type "Microsoft.WindowsAzure.Storage.Table.TableOperation"."
问题根源分析
折腾了半天终于搞明白:这是Azure PowerShell 5.1.1版本的遗留问题——它把Azure存储客户端库升级到了8.6.0.0版本,但同时还保留了旧的8.1.1.0版本,而且两个版本的库位于不同路径:
- 低版本v8.1.1.0:
C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\ResourceManager\AzureResourceManager\AzureRM.Storage - 高版本v8.6.0.0:
C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\Storage\Azure.Storage
操作Azure存储表需要用到高版本的8.6.0.0库,但默认情况下PowerShell会优先加载AzureRM.Storage文件夹里的旧版本。这就导致一个尴尬的情况:我们创建的TableOperation对象来自旧版本程序集,而CloudTable.Execute方法期望的是高版本的同类型对象——虽然名字完全一样,但属于不同程序集的类型,所以就出现了这种看似矛盾的转换错误。
解决办法
要搞定这个问题,我们需要强制PowerShell加载高版本的存储客户端库,确保所有相关对象都来自同一个版本的程序集。在脚本开头添加以下代码即可:
# 指定高版本存储库路径并加载 $assemblyPath = "C:\Program Files (x86)\Microsoft SDKs\Azure\PowerShell\Storage\Azure.Storage\Microsoft.WindowsAzure.Storage.dll" Add-Type -Path $assemblyPath $assemblySN = [System.Reflection.AssemblyName]::GetAssemblyName($assemblyPath).FullName
这样后续创建DynamicTableEntity和TableOperation时,都会基于8.6.0.0版本的程序集,类型匹配后就不会再出现转换错误了。
内容的提问来源于stack exchange,提问作者prasad metkar

