xmlpowershellvcloud-director-rest-api

Multipage xml Rest call in powershell


So I am about to face a problem in the future soon, where, my current query in Vcloud director Rest API that I left to automate, would not get all the results since it will cross the 100 items page size limit.

I can hardcode to search for page 2, but I want to actually just be able to check for the fact if its multiple pages, and if so how many, and get call for all of them and output all of them. I dont want to have to hardcode everytime I need to expand to another page.

With the following

$adminvm = Invoke-RestMethod -Uri "https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=10&format=records" -Method Get -Headers $headers

Note the Page 1

I get by parsing into $adminvm.QueryResultRecords

xmlns          : http://www.vmware.com/vcloud/v1.5
name           : adminVM
page           : 1
pageSize       : 100
total          : 62
href           : https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=100&format=records
type           : application/vnd.vmware.vcloud.query.records+xml
xsi            : http://www.w3.org/2001/XMLSchema-instance
schemaLocation : http://www.vmware.com/vcloud/v1.5 http://vcloud.example.com/api/v1.5/schema/master.xsd 
Link           : {Link, Link}
AdminVMRecord  : {TBGRCFS01, Windows Server 2008 R2 Datacenter, sagebe01, LAB-CC-DC01...}

Now, when $adminvm.QueryResultRecords.pagesize is LESS THAN $adminvm.QueryResultRecords.total :

$adminvm.QueryResultRecords.link goes from

rel       href                                            
---       ----                                         
alternate https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=100&format=references 
alternate https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=100&format=idrecords  

to

rel       href                                            
---       ----
nextPage  https://vcloud.example.com/api/query?type=adminVM&page=2&pageSize=100&format=records       
lastPage  https://vcloud.example.com/api/query?type=adminVM&page=2&pageSize=100&format=records      
alternate https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=100&format=references 
alternate https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=100&format=idrecords  

for those unfamiliar with Vcloud Rest organization, all the content tends to be in $Restcall.QueryRecords.SomethingRecord and that will contain a page worth of data ... so in this case, it will be $adminvm.QueryResultRecords.AdminVMRecord

now how should I go around working this out...even as a function.. im getting stuck

How should I approach this?

The goal is to have it autocheck if there are multiple pages, and getting data for each extra page, and output all the data TOGETHER.

I guess I should start with the if pagesize is less-than total... but not sure on the approach.... I mean I know I have to do a REST call on EACH page .. but how to do it formulaicly?


Solution

  • Wrap the call in a do{}while() loop, and then check if the nextPage link is present in the current result:

    # Set the initial URL
    $url = "https://vcloud.example.com/api/query?type=adminVM&page=1&pageSize=10&format=records"
    
    $results = do {
        # Request page
        $adminvm = Invoke-RestMethod -Uri $url -Method Get -Headers $headers
    
        # Output results
        $adminvm.QueryResultRecords.AdminVMRecord
    
    } while(($url = $adminvm.QueryResultRecords.SelectSingleNode('//link[@rel = "nextPage"]')))
    

    $results now contain the results from all queries.

    Beware that the XPath expression argument to SelectSingleNode() is case-sensitive, so @rel = "nextPage" will work, but @rel = "NextPage" won't