Get next results with @odata.nextLink field

Iron Contributor

Hi,

I'm using a powershell query to extract some data from Microsoft Defender. My query is the following:

$Vulns = "https://api.securitycenter.microsoft.com/api/machines/SoftwareVulnerabilitiesByMachine"

$vulnerabilityResponse = Invoke-WebRequest -Method Get -Uri $Vulns -Headers $headers2 -ErrorAction Stop

 

On this case, the result is limited to 50k, but in my case, the full set of data is about 200k results, so the last result from the JSON is a '@odata.nextLink' field, which is the first time I've seen, but the link on it has the next set of results.

But I don't know yet how I can I extract this 'odata.nextLink' field so I can read all the results. Anyone knows how can I read this in a cycle until the end?

 

Thanks

5 Replies

@dmarquesgn 

 

The value of '@data.nextLink' is the new URI to be used in the subsequent query.

 

Here's a nonsensical example purely for illustrative purposes, since you'd typically handle batching using one of the loop constructs:

 

Example

# Perform the initial Graph query where URI has been previously set.
$Response = Invoke-RestMethod -Method $Method -Headers $Headers -Uri $Uri 4> $null;

# Do some stuff here with the initial result set.

# Check if '@odata.nextLink' is present, since if it is, it means we are not finished and should use '@odata.nextLink' as the new value for $Uri.
if ($null -ne $Response.'@odata.nextLink')
{
    $Uri = [uri]$Response.'@odata.nextLink';
    $Response = Invoke-RestMethod -Method $Method -Headers $Headers -Uri $Uri 4> $null;     # Here, you can see that the call format is the same as above, just this time we're using the new URI.
}

# Do some stuff with the next result set, and so on and so forth.

 

Cheers,

Lain

@LainRobertson 

Hi, thanks for the comments, but something is not right here on my side.

When I check the contents of my variable which reads from the API, this is what I get:

odatanextlink1.png

Then I use your code, but the variable $uri comes out empty, so it's not being able to get the next link.

When I parse the content, this is when I see the '@odata.nextLink', like shown here:

odatanextlink.png

So it seems the 'odata.nextLink' is the last results from the content, right?

The think is how can I get this value?

@dmarquesgn 

 

You shouldn't be looking for where something is positioned within the content.

 

What you should be doing is parsing content into it's intended JSON representation using something like:

 

$Json = $vulnerabilityResponse.Content | ConvertTo-Json -Depth 5;

 

And then accessing the object properties as you would with any object, one of which will be '@odata.nextLink'.

 

I tend to use Invoke-RestMethod rather than Invoke-WebRequest since it handles the JSON conversion for me.

 

I can't test against the vulnerabilities endpoint, but there's no reason Invoke-RestMethod should not work if Invoke-WebRequest does where the expected output is JSON.

 

Cheers,

Lain

@LainRobertson 

Hi, I've did that conversion as you said, but I still have the same question. I don't have a property with the "@odata.nextLink". If I parse that new variable $Json, the link it's still there, as you can see here:

dmarquesgn_0-1702286342518.png

So I still need a way to reach that link in order to use it on the next api call. How can I get that link?

And by the way, using Invoke-RestMethod it's the same thing as well.

Thanks

@dmarquesgn 

Hi,

I was able to get the link with the Invoke-RestMethod. The code is as it follows:

$vulnerabilityResponse = Invoke-RestMethod -Method Get -Uri $Vulns -Headers $headers2 -ErrorAction Stop
$vulnerabilityResponse.'@odata.nextLink'

Thanks for the help and guidance.