Veeam Backup for Office 365 – RESTful API Coding Made Simple

Overview:

Veeam Backup for Office 365 version 1.5 has a new release just around the corner; with the increasing number of requests for RESTful API sample code, I have taken the initiative and built this user guide to help you get started with Veeam VBO RESTful API coding.

In this guide, I will demonstrate for you the development of API codes for the following tasks:

  • Enable VBO Restful API 
  • Retrieving VBO Token
  • Add VBO Proxy Server
  • List all the Proxies Server
  • Add VBO Repository Server
  • List all the Repositories Server
  • Register an Organization
  • Create a Backup Job
    • Create backup Job WorkFlow & Dependencies 
  • Restore Mailbox to PST
    • Restore Mailbox WorkFlow & Dependencies

Dependency:

Veeam VBO365 RESTful API PDF

Topics:

More Topics & Sample Codes are Coming Soon…

Enable VBO RESTful API

Overview:

Veeam Backup for Office 365 version 1.5 includes a RESTful API support. This allows service providers and customers to interact with the VBO server using the API, rather than using the VBO console.

A big benefit arising from using the API is the offer of a self-service portal; this is where service providers, or customers, can build their own web portal to offer self-service for backup or/and restoration of mailbox items, or to configure/modify the VBO server deployment.

The VBO RESTful API uses a secure tunnel between the VBO server and the interaction server (WebServer); the secure tunnel is based on a certificate that you can generate as a self-sign, or import from a third party. By default, all the API commands are carried on port number 4443.

Enable the RESTful API:

By default, the RESTful API feature is disabled, it must be enabled before beginning interactions with the VBO server. The process to enable the API is very easy; start by opening the VBO configuration, and then chose Options:

 

After you have selected the Options and the Options window appears, browse to the REST API tab to start the configuration:

All that remains now is to check the “Enable REST Service” check box, and then press “Install” to install the certificate.

Note: The HTTPS port in this example is 443. I have changed the token life time to 1440 minutes (a day).

Once completed, press Ok..

I promise you, it is easy… Time to start coding…

Retrieve Token

Overview:

Veeam Backup for Office 365 RESTful API will use a secure connection to communicate with the VBO server. This secure connection uses an SSL certificate that you must import, or generate if you choose to use a Veeam self-sign certificate before beginning your RESTful API coding. After the certificate has been applied to the server, you must retrieve, and then use a security token from the VBO server before initiating a RESTful API request.

To retrieve a Veeam VBO 365 Token, you must use the following HTTPS command:

Request:
POST https://127.0.0.1:4443/v1/Token

Request Body:
grant_type=refresh_token&refresh_token=<refresh_token>

Code:

On the example code following, we will provide a web page with a button. On pressing the button, the token will be retrieved to the browser console (Development tools – F12) and back to the browser page.

Sample Code:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>Retrieve Veeam VBO Token</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=vbotoken()”>RetrieveToken</button>
<h2 id=”preview”>Welcome</h2>

<script>
function vbotoken(){
var data = “grant_type=password&username=admin&password=admin”;

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener(“readystatechange”, function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});

xhr.open(“POST”, “https://192.168.88.88:4443/v1/Token”);
xhr.setRequestHeader(“content-type”, “application/json”);
xhr.send(data);

}
</script>
</body>
</html>

Next Step:

This token is very important; it must be used every time a request is made to the VBO server. It is recommended that you retrieve the Token and store it on a variable that will be used throughout your code. The example below will show you how to retrieve the Token, and to store it in a global variable called GlobalToken. The code under the Sample Code heading is part of the previous code, and is all that is necessary to change the xhr.addRventListener function:

Sample Code:

xhr.addEventListener(“readystatechange”, function ()
{
if (this.readyState === this.DONE) {
Globaltoken = JSON.parse(xhr.responseText);
console.log(Globaltoken);
GetToken();
function GetToken(){
document.getElementById(“preview”).innerHTML = ”;
Globaltoken = document.getElementById(“preview”).innerHTML = Globaltoken.access_token;
return console.log(Globaltoken);
xhr.send(‘json=’ + encodeURIComponent(‘[{“access_token”:””}]’));
}
}
});

 

Add VBO Proxy

Overview:

Proxy Server is a newcomer to Veeam VBO. It is used to retrieve and process the mailbox data, and store it in the VBO repository.  A service provider can add multiple Proxies from the VBO Console by using the RESTful API, shown as code under the Sample Code heading.

Request:

POST https://<Backup-Office365>:4443/v1/Proxies

Request Body:

{
“hostname”: “HostName”,
“description”: “New Proxy”,
“username”: “Domain\\username”,
“password”: “Password”,
“port”: 9193
}

Dependency:

Retrieve Token

Sample Code:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>Add new Veeam VBO Proxy</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=AddProxies()”>Add a new Proxy Server</button>
<h2 id=”preview”></h2>

<script>
function AddProxies()
{
var token_ = GlobalToken;

var data = JSON.stringify({
“hostname”: “IPAddress/Hostname”,
“description”: “New Proxy”,
“username”: “domain\\username”,
“password”: “Password”,
“port”: 9193
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener(“readystatechange”, function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});

xhr.open(“POST”, “https://VBOServerAddress:4443/v1/Proxies”);
xhr.setRequestHeader(“authorization”, “Bearer” + token_);
xhr.setRequestHeader(“content-type”, “application/json”);

xhr.send(data);

}
</script>
</body>
</html>

List All VBO Proxies

Overview:

The RESTful API shown on the next line is used to list all the proxy servers installed and available in the VBO infrastructure:

GET https://<Backup-Office365>:<Port>/v1/Proxies

That command will return all the Proxy servers initially installed, and added later, to the VBO infrastructure.

On the sample code you see below under the Sample Code heading, the function will return only the Proxy hostname using the function name: getproxy().

Also, note the Authorization = Bearer + token_  this parameter is retrieved from the GlobalToken Value, and is used instead of using the Token Key.

Dependency:

Retrieve Token

Sample Code:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>List Proxies</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=CallProxies()”>Proxy List</button>
<h2 id=”preview”>List of all of the VBO Proxies deployed will be listed here</h2>

<script>
function CallProxies()
{
var token_ = GlobalToken;

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange = function()
{
if(this.responseText.length>0){
var prox = JSON.parse(this.responseText);
getproxy();
function getproxy(){
document.getElementById(“preview”).innerHTML = ”;
for (var i = 0; i < prox.length; i++)
document.getElementById(“preview”).innerHTML += (‘<br>’) + prox[i].hostName + ” : ” + prox[i].description + (‘<br>’);
}
}
}
xmlhttp.open(“GET”, “https://VBO-IPAddress:4443/v1/Proxies”);
xmlhttp.setRequestHeader(‘Content-Type’, ‘application/json’);
xmlhttp.setRequestHeader(“Authorization”, “Bearer “+ token_);
xmlhttp.send(‘json=’ + encodeURIComponent(‘[{“hostName”:””},{“description”:””}’));
}
</script>
</body>
</html>

 

Add VBO BackupRepository

Overview:

Veeam VBO Backup Repository is a target location, where Veeam VBO save and store the backup data to. This VBO Backup repository can be configured as a folder, local or shared (experimental mode). Each backup repository must associate with a backup proxy.  Note that you can set more than one repository for one proxy.

The RESTful API commands for adding a new Backup Repository are:

Request:

POST https://<Backup-Office365>:<Port>/v1/BackupRepositories

Request Body:

{
“name”: “ABC Support”,
“proxyId”: “ProxyID”,
“retentionPeriodType”: “Daily”,
“retentionPeriodDaily”: 14,
“retentionFrequencyType”: “Daily”,
“dailyTime”: “08:00:00”,
“description”: “”,
“dailyType”: “Weekends”,
“path”: “C:\\ABC_support”,
“hostName”: “support.east.local”
}

Dependency:

Retrieve Token

List VBO Proxies

Sample Code:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>Add new Veeam VBO Backup Repository</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=AddRepository()”>Add a new Repository</button>
<h2 id=”preview”></h2>

<script>
function AddRepository()
{
var token_ = GlobalToken;

var data = JSON.stringify({
“name”: “Test Repo Creation”,
“proxyId”: “78a9f71d-383c-4377-91cf-e0f0fb4434e9”,
“retentionPeriodType”: “Daily”,
“dailyRetentionPeriod”: 14,
“retentionFrequencyType”: “Daily”,
“dailyTime”: “08:00:00”,
“description”: “Repo from RESTful API”,
“dailyType”: “Weekends”,
“path”: “C:\\MyRepo”,
“hostName”: “Hostname/IPAddress”
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener(“readystatechange”, function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});

xhr.open(“POST”, “https://VBOServerAddress:4443/v1/BackupRepositories”);
xhr.setRequestHeader(“authorization”, “Bearer” + token_);
xhr.setRequestHeader(“content-type”, “application/json”);

xhr.send(data);

}
</script>
</body>
</html>

Note:

As you can notice in the above code, the proxy ID needed to be used to add a backup repository successfully. You can retrieve the proxy ID by using the code from the “List All VBO Proxies” function. 

 

List All VBO Repositories

Overview:

The RESTful API shown on the next line is used to list all the backup repository servers installed and available in the VBO infrastructure:

GET https://<Backup-Office365>:<Port>/v1/BackupReposiotries

That command will return all the backup repository servers initially installed, and added later, to the VBO infrastructure.

On the sample code, you see below under the Sample Code heading, the function will return the Repository hostname, description, and path using the function name: getrepo().

Also, note the Authorization = Bearer + token_  this parameter is retrieved from the GlobalToken value and is used instead of using the Token Key.

Dependency:

Retrieve Token

Sample Code:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>List VBO Repository</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=CallRepo()”>List Repository</button>
<h2 id=”preview”>List of all of the VBO Backup Repositories deployed will be listed here</h2>

<script>
function CallRepo()
{
var token_ = GlobalToken;

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange = function()
{
if(this.responseText.length>0){
var repo = JSON.parse(this.responseText);
getrepo();
function getrepo(){
document.getElementById(“preview”).innerHTML = ”;
for (var i = 0; i < repo.length; i++)
document.getElementById(“preview”).innerHTML += (‘<br>’) + repo[i].name + ” : ” + repo[i].description + ” : ” + repo[i].path +(‘<br>’);
}
}
}
xmlhttp.open(“GET”, “https://VBOSrvAddress:4443/v1/BackupRepositories”);
xmlhttp.setRequestHeader(‘Content-Type’, ‘application/json’);
xmlhttp.setRequestHeader(“Authorization”, “Bearer “+ token_);
xmlhttp.send(‘json=’ + encodeURIComponent(‘[{“name”:””},{“description”:””},{“path”:””}’));
}
</script>
</body>
</html>

Register VBO Organization

Overview:

Veeam VBO Organization refers to as an Exchange Online, on-premises or hybrid organization whose mailbox database should be backed up. An organization must be registered before create and run a backup job. To register an Organization using the RESTful API command, the below commands must be employed:

Request:

POST https://<Backup-Office365>:4443/v1/Organizations

Request Body:

{
“type”: “office365“,
“Region”: “Worldwide”,
“username”: “eastsupport.onmicrosoft.com”,
“password”: “Passw0rd”,
“grantImpersonation”: “true”
}

OR

{
“type”: “onpremises“,
“serverName”: “yourmail.migrationendpoint.com”,
“username”: “support\jsmith”,
“password”: “Passw0rd”,
“GrantImpersonation”: true,
“useSSL”: “true”,
“skipCAverification”: “true”,
“skipCommonNameVerification”: “true”,
“skipRevocationCheck”: “true”,
“configureThrottlingPolicy”: “true”
}

Dependency:

Retrieve Token

Sample Code:

On this sample code, We will use the API to register an Office 365 Organization. To register an Exchange or On-Premises Organization, you can replace the type to “on premises” instead of the “office365”:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>Add new Veeam VBO Organization</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=addorg()”>Add a new Organization</button>
<h2 id=”preview”></h2>

<script>
function addorg()
{
var token_ = GlobalToken;

var data = JSON.stringify({
“type”: “office365”,
“Region”: “Worldwide”,
“username”: “subscription@onmicrosoft.com”,
“password”: “password”,
“grantImpersonation”: “true”
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener(“readystatechange”, function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});

xhr.open(“POST”, “https://VBOServerAddress:4443/v1/Organizations”);
xhr.setRequestHeader(“authorization”, “Bearer” + token_);
xhr.setRequestHeader(“content-type”, “application/json”);

xhr.send(data);

}
</script>
</body>
</html>

List all VBO Organizations

Overview:

The RESTful API shown on the next line is used to list all the registered Organization available and registered in the VBO infrastructure:

GET https://<Backup-Office365>:<Port>/v1/Organizations

That command will return all the Organization types, added to the VBO infrastructure.

On the sample code, you see below under the Sample Code heading, the function will return the Organization name, and type by the getOrg() function.

Also, note the Authorization = Bearer + token_  this parameter is retrieved from the GlobalToken value and is used instead of using the Token Key.

Dependency:

Retrieve Token

Sample Code:

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>Retrieve Veeam Organization List</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=getOrg()”>List Repository</button>
<h2 id=”preview”>List of all of the VBO Organizations will be listed here</h2>

<script>
function CallRepo()
{
var token_ = GlobalToken;

var xmlhttp = new XMLHttpRequest();

xmlhttp.onreadystatechange = function()
{
if(this.responseText.length>0){
var repo = JSON.parse(this.responseText);
getrepo();
function getrepo(){
document.getElementById(“preview”).innerHTML = ”;
for (var i = 0; i < repo.length; i++)
ocument.getElementById(“preview”).innerHTML += (‘<br>’) + orgs[i].type + ” : ” + orgs[i].serverName + ” : ” + orgs[i].name + ” : ” + orgs[i].region + (‘<br>’);
}
}
}
xmlhttp.open(“GET”, “https://VBOSrvAddress:4443/v1/Organizations”);
xmlhttp.setRequestHeader(‘Content-Type’, ‘application/json’);
xmlhttp.setRequestHeader(“Authorization”, “Bearer “+ token_);
xmlhttp.send(‘json=’ + encodeURIComponent(‘[{“type”:””},{“name”:””},{“serverName”:””},{“region”:””}’));
}
</script>
</body>
</html>

Create a new VBO Backup Job

Overview

On a shared VBO infrastructure, Service Providers prefer using a self-service portal to allow the client to set up and schedule the backup jobs. To achieve this requirement, the VBO RESTful API can be used to build a self-service backup job portal. Before deep diving into the API commands, let’s review the workflow of the VBO job creation.

Dependencies

  • Retrieve Token
  • List All VBO Proxies
  • List All VBO Repositories
  • Register VBO Organization

Workflow

To understand the workflow of creating a backup job, let’s first review what the RESTful API expects from the user to automate the process:

{
“name”: “Backup Job ABC”,
“description”: “Critical Mailboxes”,
“allMailboxes”: true,
/* “selectedMailboxes”: [
{
“id”: “ac57ab24-e4b2-4c47-a3da-43fd612323dc”,
“email”: “petep@eastsupport.onmicrosoft.com”,
“name”: “Peter Parker”,
}
],*/
“schedulePolicy”: {
“type”: “Daily”,
“periodicallyEvery”: “Hours1”,
“dailyType”: “Sunday”,
“dailyTime”: “08:00:00”,
“terminationEnabled”: false,
“terminationInterval”: “Minutes10”,
“retryEnabled”: true,
“retryNumber”: 5,
“retryWaitInterval”: 15
},
“proxyId”: “5a905bb5-9071-433c-9d2f-f805d4da2cf4”,
“repositoryId”: “5729d9cf-abfa-4077-9dd5-f5a888b98147”,
“isRun”: “true”
}

To simplify the example code, we will demonstrate backing up all the mailboxes in the organization. You can see from the above code that the RESTful API is expecting parameters to be input by the user. Let’s go ahead now and build a form that shows the workflow of the backup job creation:

Let’s discuss how the form will retrieve the following parameters:

  • OrganizationID
  • RepositoryID
  • ProxyID

As you might expect, there are many inquiries that must be sent to the VBO server to automate the running of our form above.

The Organization ID must first be retrieved to be able to submit a backup job. To get our Organization ID, run the following command:

Note: you must retrieve the token before you can continue:

GET https://VBOServerAddress:4443/v1/Organizations

The return will return many parameters; however, the important parameters needed at this stage are highlighted:

[
{
“type”: “Office365”,
“username”: “username@onmicrosoft.com”,
“region”: “Worldwide”,
“id”: “b85bbf31-f4d1-4b16-9b38-b04fa09d2ae6”,
“name”: “orgname.onmicrosoft.com”,
“isBackedup”: true,
“firstBackuptime”: “2017-08-28T06:17:09.7290562Z”,
“lastBackuptime”: “2017-09-03T22:00:06.7437024Z”,
“_links”: {
“self”: {
“href”: “https://VBOServerAddress:4443/v1/organizations/b85bbf31-f4d1-4b16-9b38-b04fa09d2ae6”
},
“jobs”: {
“href”: “https://VBOServerAddress:4443/v1/organizations/b85bbf31-f4d1-4b16-9b38-b04fa09d2ae6/jobs”
},
“mailboxes”: {
“href”: “https://VBOServerAddress:4443/v1/organizations/b85bbf31-f4d1-4b16-9b38-b04fa09d2ae6/mailboxes”
}
}]

After the parameters have been retrieved and stored on our values, the href URL will be used with the POST command to create the backup job:

POST https://VBOServerAddress:4443/v1/organizations/b85bbf31-f4d1-4b16-9b38-b04fa09d2ae6/Jobs

Now we can retrieve the Repository and Proxy IDs. The Repository cannot exist without the Proxy; you now send one request to the VBO where the return will present the two IDs. This command will save you time and complexity with your code. The command is:

GET https://VBOServerAddress:4443/v1/BackupRepositories

As we stated previously, the return will include the Repository and the Proxy IDs. They are highlighted below:

“id”: “62e91803-4dec-4564-8809-5a5915bafbd7”,
“name”: “Default Backup Repository”,
“description”: “Created by Veeam Backup for Microsoft Office 365”,
“path”: “C:\\VeeamRepository”,
“hostName”: “VBOSRV”,
“capacity”: 63829962752,
“freeSpace”: 42753105920,
“retentionPeriodType”: “Yearly”,
“yearlyRetentionPeriod”: “Years3”,
“retentionFrequencyType”: “Daily”,
“dailyTime”: “11:00:00”,
“dailyType”: “Everyday”,
“proxyId”: “78a9f71d-383c-4377-91cf-e0f0fb4434e9”,
“_links”: {
“self”: {
“href”: “https://VBOServerAddress:4443/v1/backuprepositories/62e91803-4dec-4564-8809-5a5915bafbd7”
},
“proxy”: {
“href”: “https://VBOServerAddress:4443/v1/proxies/78a9f71d-383c-4377-91cf-e0f0fb4434e9”

Now let’s summarise the workflow:

Sample Code

<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<meta name=”viewport” content=”width=device-width”>
<title>Create New Job</title>

</head>

<body>
<button onclick=”document.getElementById(‘preview’).innerHTML=NewJob()”>Create New Job</button>
<h2 id=”preview”></h2>

<script>
function NewJob(){

var token_ = GlobalToken;

var data = JSON.stringify({
“name”: “Backup Job ABC”,
“description”: “Critical Mailboxes”,
“allMailboxes”: true,
“schedulePolicy”: {
“type”: “Daily”,
“periodicallyEvery”: “Hours1”,
“dailyType”: “Sunday”,
“dailyTime”: “08:00:00”,
“terminationEnabled”: false,
“terminationInterval”: “Minutes10”,
“retryEnabled”: true,
“retryNumber”: 5,
“retryWaitInterval”: 15
},
“proxyId”: “78a9f71d-383c-4377-91cf-e0f0fb4434e9”,
“repositoryId”: “62e91803-4dec-4564-8809-5a5915bafbd7”,
“isRun”: “true”
});

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener(“readystatechange”, function () {
if (this.readyState === this.DONE) {
console.log(this.responseText);
}
});

xhr.open(“POST”, “https://VBOServerAddress:4443/v1/organizations/b85bbf31-f4d1-4b16-9b38-b04fa09d2ae6/Jobs”);
xhr.setRequestHeader(“authorization”, “Bearer” + token_);
xhr.setRequestHeader(“content-type”, “application/json”);

xhr.send(data);
}
</script>
</body>
</html>