首先,我被绑定到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方法中获取相同的对象?
提前致谢,
安迪
答案 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)
}
}