2017-03-16 45 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