Powershell - 无法将 "System.Management.Automation.PSCustomObject"类型的值转换为 "System.Management.Automation.PSCustomObject"类型

标签 powershell type-conversion powershell-4.0 powershell-cmdlet

我在 Windows 7 下使用 Powershell 4,并且我的 cmdlet 定义如下:

 Function Transfer-File {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [System.Management.Automation.PSCustomObject]
        $source,

        # other parameters removed for brevity
    )

    # actual logic does not matter 

  }

我这样称呼它:
$hasError = Transfer-File -source $source -destination $cfg.Destination -logfile $logFile

$source 是通过解析一个 JSON 文件得到的,看起来像这样:
@{Path=some path string here; Pack=False}
Write-Host $source.GetType()输出:
System.Management.Automation.PSCustomObject

我收到以下错误:

Cannot convert the "@{Path=some path string here; Pack=False}" value of type "System.Management.Automation.PSCustomObject" to type "System.Management.Automation.PSCustomObject".



在绝望的尝试中以经验方式解决它,我替换了 System.Management.Automation.PSCustomObjectpsobject它似乎工作正常。

问题:为什么我的System.Management.Automation.PSCustomObject似乎不适合 System.Management.Automation.PSCustomObject来自 cmdlet 原型(prototype)?

对象创建的完整代码:
### Configuration ###
$cfg = New-Object –TypeName PSObject
$cfg | Add-Member -MemberType NoteProperty –Name Sources –Value @()

# get configuration from json file
$jsonContent = Get-Content .\config.json |  Out-String
$jsonObj = ConvertFrom-Json $jsonContent
$cfg.Sources = $jsonObj.Sources

Foreach ($source in $cfg.Sources)
{
    # Write-Host $source.GetType()
    $hasError = Transfer-File -source $source -destination $cfg.Destination -logfile $logFile
}

最佳答案

正如@VivekKumarSingh 的评论所暗示的,这是一个 bug与加速器有关。
这将不起作用:

# Error
$y = [System.Management.Automation.PSCustomObject]@{Path='some path string here'; Pack=$False}
这将不起作用:
$y = [PSCustomObject]@{Path='some path string here'; Pack=$False}

function t ([System.Management.Automation.PSCustomObject]$x) { $x }

# Error
t $y
这将起作用:
$y = [PSCustomObject]@{Path='some path string here'; Pack=$False}

function t ([PSCustomObject]$x) { $x }

t $y
但是,上面不会将任何类型转换为 PSCustomObject , 因为该类型继承自 Object :
PS> function t ([PSCustomObject]$x) { $x.GetType().FullName }
PS> t 5
System.Int32
PS> t 'asdf'
System.String
PS> t $(Get-ChildItem)
System.Object[]
PS> t $(Get-Item .)
System.IO.DirectoryInfo
这也可以,但我不完全确定它是否 100% 等效。
function t ([System.Management.Automation.PSObject]$x) { $x }
我不确定的原因是因为这种奇怪:
PS> $a = New-Object -TypeName System.Management.Automation.PSObject -Property @{Path='some path string here'; Pack=$False}
PS> $a.GetType().FullName
System.Management.Automation.PSCustomObject

PS> $a = New-Object -TypeName System.Management.Automation.PSCustomObject -Property @{Path='some path string here'; Pack=$False}
New-Object : A constructor was not found. Cannot find an appropriate constructor for type System.Management.Automation.PSCustomObject.

PS> $a = [PSCustomObject]@{Path='some path string here'; Pack=$False}
PS> $a.GetType().FullName
System.Management.Automation.PSCustomObject

PS> $a = [System.Management.Automation.PSObject]@{Path='some path string here'; Pack=$False}
PS> $a.GetType().FullName
System.Collections.Hashtable

PS> $a = [PSObject]@{Path='some path string here'; Pack=$False}
PS> $a.GetType().FullName
System.Collections.Hashtable
据我所知,[PSCustomObject][PSObject]都是 System.Management.Automation.PSObject 的加速器. System.Management.Automation.PSCustomObject只是他们添加的实现细节 [PSCustomObject]可能,但不幸的是,一切工作的方式感觉有点不一致。我不完全清楚 [PSObject] 是什么但是,类型加速器适用于。它似乎什么也没做,但它也确实存在:
PS> ([System.Management.Automation.Cmdlet]).Assembly.GetType('System.Management.Automation.TypeAccelerators')::Get.ContainsKey('psobject')
True

关于Powershell - 无法将 "System.Management.Automation.PSCustomObject"类型的值转换为 "System.Management.Automation.PSCustomObject"类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49152776/

相关文章:

c++ - 如何从 BYTE* 转换为 QString?

powershell - 无法访问 AWS 上的 ElasticSearch

windows - Powershell 在 -Exclude 中删除具有精确扩展名的文件

c# - DerivedClass 作为 ParentClass 类型变量的值

sql-server - 如何更改 SQL Server 中列的数据类型?

json - 在powershell中用空字符串键解析json

powershell - 如何在powershell中将字符串转换为表格或对象

powershell - 在 Powershell 中设置像 yyyy-mm-dd 这样的默认日期格式?

powershell - 从基于文本的表输出中提取列

powershell - 使用Authenticationn/Access token 访问TeamCity时出现错误401未经授权