1

我使用Invoke-RestMethod -Uri https://.... 调用的结果 inJSON可以通过管道将数据传输到Format-Table -Property ...并显示数据。

但是当Select-Object -Property ...在调用后使用相同的参数时,PSObject有列但没有数据。如果我使用不同的网络服务,呼叫将起作用。

在此处输入图像描述

什么可能导致PSObject不显示任何值?


公共休息网络服务的工作示例

Invoke-RestMethod -Uri https://jsonplaceholder.typicode.com/todos/1 |
Select-Object -Property title

结果

@{title=delectus aut autem}

新的失败不同的 API

Invoke-RestMethod -Uri https://cat-fact.herokuapp.com/facts | Select-Object -Property text

在此处输入图像描述

4

2 回答 2

4

在转换 JSON数组时,您偶然发现了两个 PowerShell 怪异的邪恶组合:

  • Invoke-RestMethod并像往常一样通过管道ConvertFrom-Json发送从 JSON 转换而来的数组作为一个整体,而不是逐个元素地发送:

    • 注意:在PowerShell (Core) 7.0中, ComvertFrom-Json更改了 的行为以与通常的元素枚举行为保持一致,并-NoEnumerate添加了一个开关作为对旧行为的选择。有关导致此更改的讨论,请参阅GitHub 问题 #3424

    • 但是,在撰写本文时(PowerShell (Core 7.2)Invoke-RestMethod仍然表现出这种意外行为,这在GitHub 问题 #15272中进行了讨论。

  • Select-Object不执行成员枚举,因此它直接在不存在的数组上查找指定的属性(例如,text) 。

用一个简单的例子来演示这个问题:

# Windows PowerShell only:
# Because ConvertFrom-Json sends an *array* (of 2 custom objects) through
# the pipeline, Select-Object looks for property .text on the *array* -
# and can't find it.
# The same applies to Invoke-RestMethod (also still in 
# PowerShell (Core) as of v7.2)
PS> ConvertFrom-Json '[{ "text": "a" }, { "text": "b" }]' | Select-Object text

text
----
       # NO VALUES 

一个简单的解决方法是将ConvertFrom-Json/Invoke-RestMethod调用包含在 中(...),这会强制枚举数组,从而Select-Object按预期工作。:

# (...) forces enumeration
PS> (ConvertFrom-Json '[{ "text": "a" }, { "text": "b" }]') | Select-Object text

text
----
a
b

请注意,诸如Select-Object -Property text(without -ExpandProperty) 之类的命令仍会输出具有.text属性的自定义对象,而不是.text属性

如果你感兴趣的只是属性,那么解决方案就更简单了,因为你可以直接在数组上使用上面提到的成员枚举:

# Using .<propName> on an array (collection) implicitly returns the
# property values from the *elements* of that collection (member enumeration).
PS> (ConvertFrom-Json '[{ "text": "a" }, { "text": "b" }]').text
a
b

注意输出现在没有text标题,因为它只是输出的字符串值 ,而不是自定义对象。

于 2019-07-06T21:14:20.697 回答
3

您在第二个示例中的问题是没有名为的道具text。[咧嘴笑]

唯一的道具是all并且包含一个对象数组,其中包含一个名为 的道具text。所以你需要一些可以得到更深的道具的东西。一种方法是使用两个Select-Object调用。像这样的东西......

$Url = 'https://cat-fact.herokuapp.com/facts'
$RawIRM = Invoke-RestMethod -Uri $Url 
$SO_IRM = $RawIRM |
    Select-Object -ExpandProperty all |
    Select-Object -Property text

var 现在有一个包含 178 个关于猫的字符串的$SO_IRM数组。[咧嘴笑]

于 2019-07-06T20:29:21.173 回答