使用Powershell invoke-restmethod和json响应

时间:2018-07-31 15:17:52

标签: json powershell

这里非常有Powershell和JSON的新手,因此可能需要一些额外的帮助。不是编码员,菲。

我正在使用Dell的API来检索机器上的保修信息。如果可能,我想在Powershell中进行。

到目前为止,这是我的代码-

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("apikey", 'mykey')
$response = Invoke-RestMethod https://sandbox.api.dell.com/support/assetinfo/v4/getassetwarranty/servicecode -Headers $headers -contenttype 'application/json'

如果我看着$response,这是输出-

AssetWarrantyResponse : {@{AssetHeaderData=; ProductHeaderData=; AssetEntitlementData=System.Object[]}}
InvalidFormatAssets   : @{BadAssets=System.Object[]}
InvalidBILAssets      : @{BadAssets=System.Object[]}
ExcessTags            : @{BadAssets=System.Object[]}
AdditionalInformation :

进行了一些挖掘,发现如果我使用下面的代码,我可以开始查看实际数据-

$response.AssetWarrantyResponse|fl

AssetHeaderData      : @{BUID=11; ServiceTag=....
ProductHeaderData    : @{SystemDescription=Op....
AssetEntitlementData : {@{StartDate=2017-11-2....

我看到有一个来自convertjson的命令。看起来这将获得响应,并使其在Powershell中使用起来更加容易。但是我无法为我的一生做这项工作。我正在尝试从上面的AssetHeaderDataAssetEntitlementData中提取一些数据。我敢肯定我可以做一些正则表达式,但是如果有更简单的方法,我将全力以赴!

感谢您的帮助。谢谢!

1 个答案:

答案 0 :(得分:5)

您做得很棒!您将看到PowerShell在屏幕上显示数据的系统。由于PowerShell倾向于处理复杂的对象,因此您处理的不仅仅是格式化的字符串输出,就像从常规Shell命令中看到的一样。

在这种情况下,Invoke-RestMethod已自动为您完成了ConvertFrom-Json的等效工作,也就是说,它已经提取了API返回的JSON并从中创建了一个对象。

该对象具有各种属性,例如.AssetWarrantyResponse,每个属性可以是一个值或一个数组或另一个对象。

因此,在问题的第一个$response转储中,您在输出中看到的是响应对象具有的属性以及这些属性的值。

这些值看起来很有趣,因为它们本身是对象,其中一些包含数组,并且难以一次格式化所有内容。

您已经发现可以直接引用属性,例如通过使用$response.AssetWarrantyResponse

查看时,您会看到更多属性,它们也是对象。我认为,根据您发布的输出,它不会嵌套得更深。

因此,要查看所需属性的内容,请继续挖掘:

$response.AssetWarrantyResponse.AssetHeaderData
$response.AssetWarrantyResponse.AssetEntitlementData

您根本不需要正则表达式,因为数据已经适当地分解了。

如果您还有其他需要处理的内容,请将其编辑为您的问题(或在必要时发布新问题),我们也可以为您提供帮助。

根据评论进行更新

选项卡完成可能是挑剔的。但是,当我再次查看您的数据时,我想我明白了为什么您看到了您看到的内容,并且制表符补全工作正常。

AssetWarrantyResponse是单个属性,它将制表符完整。其 value 是一个数组。因此,尝试执行.AssetWarrantyResponse.AssetHeaderData不会完成制表符的操作,因为它不是对象(数组)的属性。

如果您进行了$response.AssetWarrantyResponse[0].AssetHeaderData,则制表符补全将起作用。

仅在键入时“起作用”的原因是由于PowerShell v3中的更改。

在v3之前,如果您有一个对象数组,并且想要获取每个对象的.Thing属性的数组,则必须自己枚举:

$things = foreach($item in $arr) {
    $arr.Thing
}

v3添加了一项简洁的功能,您只需执行$things = $arr.Thing即可为您处理所有这一切。但是,由于数组中的每个项目可能完全不同且具有不同的属性,所以制表符补全不会尝试进入每个条目并阅读它们并决定要制表符补全的内容;您必须先取消引用自己的单个项目,然后制表符完成才能按预期工作。

因此,即使您想使用v3的优点,也可以使用制表符完成功能,而无需额外输入以下内容:

$response.AssetW TAB [0].AssetH TAB

然后只需返回并删除[0]

请记住,如果该属性是一个数组,您可能应该期望.AssetWarrantyResponse.AssetHeaderData也可以是一个数组,因此在接下来的内容中,您必须适当地处理这种情况。

如果您不关心这种情况,而只想要第一项,请使用[0](如果只希望最后一项,请使用[-1])。关键是,如果您想假设它只会是单个元素,请确保代码能够处理该假设,这样它就不会在边缘情况下做奇怪的事情。