2017-03-16 49 views
1

我正在使用PowerShell调用GitHub API。结果是一个JSON数组,我使用ConvertFrom-Json cmdlet将其转换为PowerShell对象。这给了我一个PowerShell对象数组。然而,当我管这个直接选择 - 对象,我得到什么:Powershell调用Github API:ConvertFrom-Json管道之谜

Invoke-WebRequest -Uri "https://api.github.com/organizations?per_page=3" | ConvertFrom-Json | Select-Object -Property login, id 

但是,如果我把ConvertFrom-JSON结果到一个变量,然后传递变量来选择对象时,它的工作原理:

$json = Invoke-WebRequest -Uri "https://api.github.com/organizations?per_page=3" | ConvertFrom-Json 
$json | Select-Object -Property login, id 

我很困惑。为什么单行版本不起作用?

+1

我不确定为什么发生这种情况,但如果使用invoke-restmethod,则不需要使用convertfrom-json,因为它会自动将其转换为对象。 –

+0

我不知道Invoke-RestMethod - 谢谢 - 这很好。尽管如此,我仍然需要临时变量。神秘仍然存在。 – Edward

+0

这里的示例2建议您的代码应该正常工作https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.utility/convertfrom-json –

回答

1

我不知道为什么一个衬垫不以目前的形式工作,但这可能解决它:

(Invoke-WebRequest -Uri "https://api.github.com/organizations?per_page=3").content | ConvertFrom-Json | Select-Object -Property login, id 

或者你也可以做到这一点,而不是:

(Invoke-RestMethod -Uri "https://api.github.com/organizations?per_page=3") | Select-Object -Property login, id 
+0

优秀 - 你的第一个例子有效(我不需要.content,但它也没有坏处)。你的第二个例子不工作,我需要添加括号。所以我现在的问题是:为什么我需要临时变量或括号来使它工作? – Edward

+0

这可能与Invoke-WebRequest如何开始将事情发送到管道有关,我的猜测是括号可以确保命令在完成之前完全完成。但是可能有人会对可能会回答的PowerShell内部有更多的了解。 –

1

这发生是因为这是PowerShell的工作原理。

Invoke-WebRequest -Uri "https://api.github.com/organizations?per_page=3" | ConvertFrom-Json | Get-Member 

返回一个数组,所以如果你开始做的阵列select-object,它不会工作,因为数组没有这些特性,你可以解决,通过管道来的foreach:

Invoke-WebRequest -Uri "https://api.github.com/organizations?per_page=3" | ConvertFrom-Json | Foreach-Object { $_ | select id,login } 

编辑:Invoke-RestMethod是更好的方法。 edit2:命令周围的括号会使该命令执行并在命令完成时发送整个输出,因此管道仅在命令完成后启动,但第一个结果准备就绪时才启动。

0

原因似乎是,Invoke-WebRequestInvoke-RestMethod将它们的输出作为单个项输出到管道,即使该输出是数组。将输出存储在一个变量中,然后管道输入,或者在一个子表达式中运行Web请求会导致数组元素被放入管道而不是数组本身。

> Invoke-RestMethod -Uri "https://api.github.com/organizations?per_page=3" | % { $_.GetType() } 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  True  Object[]         System.Array 


> (Invoke-RestMethod -Uri "https://api.github.com/organizations?per_page=3") | % { $_.GetType() } 

IsPublic IsSerial Name          BaseType 
-------- -------- ----          -------- 
True  False PSCustomObject       System.Object 
True  False PSCustomObject       System.Object 
True  False PSCustomObject       System.Object