As a VMware Site Recovery Manager enthusiast I was very interested in the new Veeam Availability Orchestrator. And finally I found the time to deploy and configure the new rising start in the Veeam Software portfolio. Even in version 1.0 the Veeam Availability Orchestrator is already a great product and will help a lot of customers to create a reliable Disaster Recovery concept. During my configuration process I was wondering that there is no PowerShell Module for Veeam Availability Orchestrator available. But wait there is an API, so I started to create my own PowerShell Module.
Veeam has done a great job with the API Implementation. There is a great documentation and even a Swagger interface available.
If you are interested in detail about installation and configuration of Veeam Availability Orchestrator I would recommend some great blog posts from my Veeam Vanguard fellows:
Creating a PowerShell Module for Veeam Availability Orchestrator
If a well-documented RESTFul API is available it is not very complex to get started with the right Tools. One of the most important Tools for me while working with RESTFul API is Postman.
Understand and verify the API calls
Before I start working on the PowerShell Module i try to understand the API and verify the calls i want to use in my PowerShell Module. Postman has also the capability to import Swagger File into a collection (Url: https://:9899/swagger/docs/v1). After the Import only a few optimizations need to done:
Postman can run scripts after the API Call (tests). You can use these scripts to extract data from the response and write it to the Environment. These filled variables can then be used in further API calls. In case of the Veeam Availablity Orchestrator API we need the tokens:
1
2
3
|
var body = JSON.parse(responseBody)
pm.environment.set("refresh_token", body.refresh_token);
pm.environment.set("access_token", body.access_token);
|
To be more flexible it is a common practice in postman to work with variables in call Url, Header and Body.
I have exported my optimized Postman Collection into the GitHub Repository of the project.
Create PowerShell Module
Disclaimer:
What I am sharing here is just my practice to create a RESTFul API PowerShell Module and not the Best Practice to do this. There are way better modules available to show how to do is more efficient (e.g. VMware PowerNSX).
When I start building a RESTFul API based PowerShell Module I try to create two main initial functions, a function to connect to the API and another function as a helper for the general API calls. The connection function should also store the connection details, used by the general API call function. All further functions for application specific calls are based on the general API call function.
Connection function
Veeam Availability Orchestrator API authorization process is based on the OAuth 2.0 Authorization Framework.
More Details: Veeam Availability Orchestrator 1.0 RESTful API Reference - Authorization and Security
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
#region: Workaround for SelfSigned Cert and force TLS 1.2
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
#endregion
Function New-VaoApiConnection {
<#
.DESCRIPTION
Connecto to Veeam Availability Orchestrator API.
.NOTES
File Name : New-VaoApiConnectionl.psm1
Author : Markus Kraus
Version : 1.0
State : Ready
.LINK
https://mycloudrevolution.com/
.LINK
https://helpcenter.veeam.com/docs/vao/restapi/overview.html?ver=10
.EXAMPLE
$YourCredentials = Get-Credential
New-VaoApiConnection -Server "vao01.lab.local" -Credential $YourCredentials
.PARAMETER Server
FQDN of the Veeam Availability Orchestrator Instance
.PARAMETER Token
Existing Token for renewal (not yet implemented)
.PARAMETER Credential
Credential for the Veeam Availability Orchestrator Instance
#>
Param (
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="FQDN of the Veeam Availability Orchestrator Instance")]
[ValidateNotNullorEmpty()]
[String]$Server,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Existing Token for renewal (not yet implemented)")]
[ValidateNotNullorEmpty()]
[String]$Token = $Global:VaoApiConnection.Token,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Credential for the Veeam Availability Orchestrator Instance")]
[ValidateNotNullorEmpty()]
[Management.Automation.PSCredential]$Credential
)
Process {
try {
$FullUri = "https://" + $Server + ":9899" + "/v1/About"
$Headers = @{'Accept' = 'application/json, text/json, text/html, application/xml, text/xml'}
$Return = Invoke-RestMethod -uri $FullUri -Method Get -Headers $Headers
}
catch {
Throw "Failed to contact Veeam Availability Orchestrator API. Login aborted!"
}
$username = $Credential.UserName
$password = $Credential.GetNetworkCredential().Password
$FullUri = "https://" + $Server + ":9899" + "/v1/Accounts/Token"
$Headers = @{'Content-Type' = 'application/x-www-form-urlencoded'}
$Body = @{ grant_type = 'password';
username = $username;
password = $password;
refresh_token = $Token
}
$Return = Invoke-RestMethod -uri $FullUri -Method POST -Headers $Headers -Body $Body
#region: Cleanup Confidential Data
Clear-Variable -Name username, password
#endregion
#region: Build Connection Variable
$Global:VaoApiConnection = [pscustomobject]@{
Server = $Server
access_token = [String]$Return.access_token
refresh_token = [String]$Return.refresh_token
token_type = [String]$Return.token_type
}
#endregion
$Global:VaoApiConnection
}
}
|
General API call function
The API call helper function uses per default the recommended headers for the Veeam Availability Orchestrator API endpoint. The header also includes the authentication token.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#region: Workaround for SelfSigned Cert and force TLS 1.2
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
[System.Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
#endregion
Function Invoke-VaoApiCall {
<#
.DESCRIPTION
Helper function to call the Veeam Availability Orchestrator API.
.NOTES
File Name : Invoke-VaoApiCall.psm1
Author : Markus Kraus
Version : 1.0
State : Ready
.LINK
https://mycloudrevolution.com/
.LINK
https://helpcenter.veeam.com/docs/vao/restapi/overview.html?ver=10
.EXAMPLE
Invoke-VaoApiCall -Uri "/v1/About" -Method Get
.PARAMETER Server
FQDN of the Veeam Availability Orchestrator Instance
.PARAMETER Token
Bearer Token for the Veeam Availability Orchestrator Instance
.PARAMETER Uri
API Uri for the Call
.PARAMETER Accept
Accept Header for the API Call
.PARAMETER Methode
Methode of the API Call
.PARAMETER Body
Body of the API Call
#>
Param (
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="FQDN of the Veeam Availability Orchestrator Instance")]
[ValidateNotNullorEmpty()]
[String]$Server = $Global:VaoApiConnection.Server,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Bearer Token for the Veeam Availability Orchestrator Instance")]
[ValidateNotNullorEmpty()]
[String]$Token = $Global:VaoApiConnection.access_token,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="API Uri for the Call")]
[ValidateNotNullorEmpty()]
[String]$Uri,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Accept Header for the API Call")]
[ValidateNotNullorEmpty()]
[String]$Accept = "application/json, text/json, text/html, application/xml, text/xml",
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Method of the API Call")]
[ValidateNotNullorEmpty()]
[ValidateSet("Get","Post")]
[String]$Method,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Body of the API Call")]
[ValidateNotNullorEmpty()]
$Body
)
Process {
$FullToken = "Bearer " + $Token
#region: RESTful API Call
if ($Method -like "Get" ) {
$FullUri = "https://" + $Server + ":9899" + $Uri
$Headers = @{'accept' = $Accept;'Authorization' = $FullToken}
$Return = Invoke-RestMethod -uri $FullUri -Method $Method -Headers $Headers
}
elseif ($Method -like "Post") {
if ($Body) {
$FullUri = "https://" + $Server + ":9899" + $Uri
$Headers = @{'accept' = $Accept;'Authorization' = $FullToken}
$Return = Invoke-RestMethod -uri $FullUri -Method $Method -Headers $Headers -Body $Body
}
else {
$FullUri = "https://" + $Server + ":9899" + $Uri
$Headers = @{'accept' = $Accept;'Authorization' = $FullToken}
$Return = Invoke-RestMethod -uri $FullUri -Method $Method -Headers $Headers
}
}
#edregion
$Return
}
}
|
Application specific function
This is an example of a function included in the PowerShell Module for Veeam Availability Orchestrator based on the general API call function. In line 32 and 35 (depending on input) the general API call function is called.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
Function Get-VaoSite {
<#
.DESCRIPTION
Get Veeam Availability Orchestrator Sites
.NOTES
File Name : Get-VaoSite.psm1
Author : Markus Kraus
Version : 1.0
State : Ready
.LINK
https://mycloudrevolution.com/
.EXAMPLE
Get-VaoSite | Select-Object name, id, serverName, type | ft -AutoSize
.EXAMPLE
Get-VaoSite -SiteID 850316df-d73f-4e8b-b8bc-7b1815fb0a9e | Select-Object name, id, serverName, type | ft -AutoSize
.PARAMETER SiteID
Optional Veeam Availability Orchestrator Site ID
#>
Param (
[Parameter(Mandatory=$False, ValueFromPipeline=$False, HelpMessage="Optional Veeam Availability Orchestrator Site ID")]
[ValidateNotNullorEmpty()]
[String]$SiteID
)
Process {
if ($SiteID) {
$Return = Invoke-VaoApiCall -Uri "/v1/Sites/$SiteID" -Method Get
}
else {
$Return = Invoke-VaoApiCall -Uri "/v1/Sites" -Method Get
}
$Return
}
}
|
PowerShell Module for Veeam Availability Orchestrator
New-VaoApiConnection
At first a connection to the Veeam Availability Orchestrator (VAO) instance needs to be established. The New-VaoApiConnection function authenticates with given credentials and saved the Authorization Token together with the environment details as a global variable for further use in other functions of the PowerShell Module for Veeam Availability Orchestrator.
The API can also refresh an existing token but this feature is not yet implemented.
Documentation of the function: New-VaoApiConnection
Get-VaoSite
The Get-VaoSite function can be used to get a list of all registered VAO sites or to get a representation of a VAO site with the specified ID.
Documentation of the function: Get-VaoSite
Properties:
Property |
Type |
Description |
name |
string |
Name of a VAO site. |
id |
string |
System ID assigned to a VAO site in Veeam Availability Orchestrator RESTful API. |
serverName |
string |
Name of a machine on which a VAO site is registered. |
contactName |
string |
Contact name of a person responsible for monitoring VAO performance. |
contactEmail |
string |
Email of a person responsible for monitoring VAO performance. |
contactTel |
string |
Telephone number of a person responsible for monitoring VAO performance. |
description |
string |
Description of a VAO site. |
type |
string |
Type of a VAO site. |
_links |
dictionary of string [key] and object [value] |
Links to related resources (navigation property). |
Source: https://helpcenter.veeam.com/docs/vao/restapi/sites_properties.html?ver=10
Get-VaoFailoverPlan
The Get-VaoFailoverPlan function can be used to get a list of all created failover plans or to get a list of all failover plans created for a VAO site with the specified ID.
Documentation of the function: Get-VaoFailoverPlan
Properties:
Property |
Type |
Description |
name |
string |
Name of a failover plan. |
id |
string |
System ID assigned to a failover plan in Veeam Availability Orchestrator RESTful API. |
contactName |
string |
Contact name of a person responsible for monitoring VAO performance. |
contactEmail |
string |
Contact email of a person responsible for monitoring VAO performance. |
contactTel |
string |
Telephone number of a person responsible for monitoring VAO performance. |
description |
string |
Description of a failover plan. |
planState |
string |
Current state of a failover plan. |
planStateDetails |
string |
Provides additional details on processing a failover plan and shows the number of errors and warnings occurred. |
scheduleEnabled |
boolean |
Defines whether a failover plan has a configured schedule. |
scheduleType |
string |
Defines whether a failover plan will run at specific time (OnTime) or right after another plan (AfterPlan). |
scheduleAfter |
string |
System ID of a preceding failover plan. |
scheduleAfterPlanName |
string |
Name of a preceding failover plan. |
scheduleTime |
string |
Date and time when a failover plan will run. |
siteId |
string |
System ID of a VAO site for which a failover plan is created. |
_links |
dictionary of string [key] and object [value] |
Links to related resources (navigation property). |
Source: https://helpcenter.veeam.com/docs/vao/restapi/failoverplans_properties.html?ver=10
Set-VaoFailoverPlan
The Set-VaoFailoverPlan can be used, in the version 1.0 of the module, to enable or disable the given Failover Plan.
The API has a lot of more Operations and Methods for Failover Plans. Maybe some of them will be implemented in future versions of the PowerShell Module for Veeam Availability Orchestrator.
Documentation of the function: Set-VaoFailoverPlan