PowerShell v2从函数返回时将Dictionary转换为Array

时间:2015-10-01 12:26:40

标签: json function powershell powershell-v2.0

首先,我被绑定到PowerShell v2,因为这是Windows 7上默认安装的内容。我想要做的事情是开箱即用的PowerShell v4,可能还有PowerShell v3。

我想从文件中读取JSON对象,并将其用作脚本中的对象。 PowerShell v2没有ConvertFrom-Json方法,所以我编写了自己的实现,我希望它具有相同的功能:

function ConvertFrom-Json
{
    param(
        [Parameter(ValueFromPipeline=$true)]
        [string]$json
    )
        [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
    $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
    $obj = $ser.DeserializeObject($json)

    Write-Host $obj.GetType()

    return $obj
}        

我这样称呼这个函数:

$configObj =  (Get-Content $configFile) -join "`n" | ConvertFrom-Json
Write-Host $configObj.GetType()

输出:

System.Collections.Generic.Dictionary`2[System.String,System.Object]
System.Object[]

而且我无法像对象那样与$ configObj进行交互并获得它的属性。事实上,我无法弄清楚如何从中获取任何信息。当我打印对象时,输出看起来像:

AC    Version        Location                                                                                                                                                                                           
---    -------        --------                                                                                                                                                                                           
True   v2.0.50727         C:\Windows\assembly\GAC_MSIL\System.Web.Extensions\3.5.0.0__31bf3856ad364e35\System.Web.Extensions.dll                                                                                             

Key   : DownloadURL
Value : https://example.com

Key   : dir
Value : 

当我希望它看起来像:

Key                                                                                                          Value                                                                                                       
---                                                                                                          -----                                                                                                       
DownloadURL                                                                                                  https://example.com          
dir 

有没有办法解决这个问题,并从我的方法中存在的ConvertFrom-Json方法中获取相同的对象?

提前致谢,

安迪

1 个答案:

答案 0 :(得分:1)

每个语句的结果,除了赋值和递增/递减之外,都被认为是函数返回的一部分。您不必使用return语句从函数返回一些内容。因此,您的函数实际上返回两个对象:Assembly方法中加载的LoadWithPartialName对象和$obj变量中的字典。将多个函数结果分配给变量时,PowerShell必须将结果打包到数组中。由于您实际上不需要Assembly个对象,因此您可以将LoadWithPartialName方法的结果投射到[void]

[void][System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions"‌​)

同样LoadWithPartialName方法是Obsolete,您根本不应该使用它。对于加载程序集,您可以使用Add-Type内置cmdlet:

Add-Type -AssemblyName System.Web.Extensions

由于您未在函数中使用命名块,因此所有代码都被视为end块,因此您只需处理函数中的最后一个管道输入。您应该使用process块来处理每个管道输入对象:

process{
    $ser.DeserializeObject($json)
}

当语句返回集合时,PowerShell枚举此集合并将每个集合的项而不是集合写为单个元素。因此,如果您的JSON包含顶级数组,则函数将返回数组元素而不是数组本身,就像内置ConvertFrom-Json那样。您可以使用一元数组运算符来防止枚举返回的数组:

,$ser.DeserializeObject($json)

总数:

function ConvertFrom-Json {
    param(
        [Parameter(ValueFromPipeline=$true)]
        [string]$json
    )
    begin {
        Add-Type -AssemblyName System.Web.Extensions
        $ser = New-Object System.Web.Script.Serialization.JavaScriptSerializer
    }
    process {
        ,$ser.DeserializeObject($json)
    }
}