Veeam Enterprise Manager : Invoke-WebRequest v Invoke-RestMethod

In the past, I have written posts, /2017/07/25/veeam-restful-api-postman/, about using Postman to make RESTful API calls against Veeam Enterprise Manager. But what if you wanted to use good old Powershell to make the calls, how would you go about retrieving your authentication tokens?

Recap

Before I start, let’s have a quick overview of Veeam Enterprise Manager (VEM) and the features available

• Available in Enterprise & Enterprise Plus
• Limited in Standard to just reporting/monitoring
• Web-based management/reporting
• Enables self-serve restores
• Separate product to VBR but included with installed ISO (at no extra cost)
• Provides Web Service API
• Works with any browser or client application that supports HTTP and HTTPS

http://<Enterprise-Manager>:9399/web

 

Access tokens

When making REST API call, we need an authentication token to allow the calls to be completed. VEM will exchange validated credentials for an authentication token and uses the ‘X-RestSvcSessionId’ header to issue tokens.

Within Powershell, there are two cmdlets we can use to make our API call

Invoke-WebRequest
And
Invoke-RestMethod

Both offer similar results, however for retrieving you authentication token from Enterprise Manager, Invoke-WebRequest is the preferred option.

Why?” I hear you ask. Good question and the answer lies in where Veeam Enterprise Manager stores the authentication token in the response.

Whenever an authentication token is requested using the Invoke-WebRequest command, VEM will issue the token in the header of its response, in the ‘X-RestSvcSessionID‘ section.

However, when we make the same authentication token request using Invoke-RestMethod command, we receive no headers, only an XML response.

Why does this matter?

Well each subsequent RESTful API call to VEM must include the authentication token contained within the header. Of course, you will want to script generating the token and storing it as a variable, for ease of use. However, if you use the Invoke-RestMethod way, then the header information is omitted and thus the authentication token cannot be retrieved and stored for later use in the header.

Example of storing and calling token

$VEMIP = "vem.lab.local"
# POST - Authorization
$Auth = @{uri = "http://" + $VEMIP + ":9399/api/sessionMngr/?v=latest";
Method = 'POST';
Headers = @{Authorization = 'Basic ' + 'bmljZXRyeTpub3RoaW5ndG9zZWVoZXJl';}
}
$AuthXML = Invoke-WebRequest @Auth
$Token = $AuthXML.Headers['X-RestSvcSessionId']

 

If I now call the $Token variable, I can see my authentication token

Let’s now make a REST call, say the number of failed jobs, we can use the following code, utilising the $token variable:-

$VEMIP = "vem.lab.local"
$Sessions = @{uri = "http://" + $VEMIP + ":9399/api/reports/summary/job_statistics";
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $token;
} #end headers hash table
}
[xml]$SessionsXML = invoke-restmethod @Sessions
$FailedJobRuns = $SessionsXML.JobStatisticsReportFrame.FailedJobRuns
$FailedJobRuns

 

Now let’s try running the same authentication code block, but using Invoke-RestMethod.

$VEMIP = "vem.lab.local"
# POST - Authorization
$Auth = @{uri = "http://" + $VEMIP + ":9399/api/sessionMngr/?v=latest";
Method = 'POST';
Headers = @{Authorization = 'Basic ' + 'bmljZXRyeTpub3RoaW5ndG9zZWVoZXJl';}
}
$AuthXML = Invoke-RestMethod @Auth
$Token = $AuthXML.Headers['X-RestSvcSessionId']

 

The error we receive is

Because there is no header information returned with Invoke-RestMethod, we can’t retrieve the required token.

There we have it a relatively small tip, but it can have a big impact on your scripts.