Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
function New-VeeamTenant {
<#
.SYNOPSIS
Creates a vCloud Tenant Configuguration for Veeam Backuo & Replication
.DESCRIPTION
Creates a vCloud tenent Configuration for Veeam Backup & Replication.
The Function leverages the Veeam Ent. Manager API. The Backup Jobs need to be created seperate
.PARAMETER ServerFQDN
Veeam Ent. Manager FQDN / IP
.PARAMETER ServerCredential
Credentials for the API
.PARAMETER OrgName
vCloud Director Org Name
.PARAMETER JobTemplateName
Veeam Job Template Name
.PARAMETER RepoName
Veeam Repository Name
.PARAMETER RepoQuota
Beeam Repository Quota in GB
.EXAMPLE
New-VeeamTenant -ServerFQDN "<Server>" -ServerCredential $(Get-Credential) -OrgName "Dummy" -JobTemplateName "Template-vCloud-Default" -RepoName "SOR_06" -RepoQuota 1024
.NOTES
Tested Version:
- PowerShell 5.1
- Veeam Backup & Replication 9.5 U3a
- vCloud Director 9.0
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Veeam Ent. Server FQDN")]
[ValidateNotNullorEmpty()]
[String] $ServerFQDN,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Veeam Ent. Server Credential")]
[ValidateNotNullorEmpty()]
[PSCredential] $ServerCredential,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="vCD Org Name")]
[ValidateNotNullorEmpty()]
[String] $OrgName,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Veeam Job Template Name")]
[ValidateNotNullorEmpty()]
[String] $JobTemplateName,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Veeam Repository Name")]
[ValidateNotNullorEmpty()]
[String] $RepoName,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, HelpMessage="Veeam Repository Quota in GB")]
[ValidateNotNullorEmpty()]
[Long] $RepoQuota
)
begin {
#region: Workaround for SelfSigned Cert
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
#endregion
#region: POST - Authorization
[String] $URL = "https://" + $ServerFQDN + ":9398/api/sessionMngr/?v=latest"
Write-Verbose "Authorization Url: $URL"
$Auth = @{uri = $URL;
Method = 'POST';
}
try {
$AuthXML = Invoke-WebRequest @Auth -ErrorAction Stop -Credential $ServerCredential
}
catch {
Throw "Authentication Failed!"
}
#endregion
#region: GET - Get BR Server
"Get All Registered Veeam Server..."
[String] $URL = "https://" + $ServerFQDN + ":9398/api/backupServers?format=Entity"
Write-Verbose "Get BR Server Url: $URL"
$BRServer = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$BRServerXML = Invoke-RestMethod @BRServer -ErrorAction Stop
$BRServerXML.BackupServers.BackupServer | Select-Object Name, UID, Version | Format-Table -AutoSize
$BRServerUID = $BRServerXML.BackupServers.BackupServer.UID
#endregion
#region: GET - Get BR Template Job
"Get all Backup Jobs to filter Template..."
[String] $URL = "https://" + $ServerFQDN + ":9398/api/jobs?format=Entity"
$BRJobs = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$BRJobsXML = Invoke-RestMethod @BRJobs -ErrorAction Stop
$BRJobsXML.Jobs.Job | Select-Object Name, UID, Platform | Format-Table -AutoSize
"Get Backup Job Template..."
foreach ($Job in $BRJobsXML.Jobs.job) {
if ($job.name -eq $JobTemplateName) {$JobTemplateXML = $Job}
}
if (!($JobTemplateXML)) {
Throw "No Job Template with name '$JobTemplateName' found!"
}
$JobTemplateXML | Select-Object Name, UID, Description | Format-Table -AutoSize
$BRJobUID = $JobTemplateXML.uid
#endregion
#region: GET - Get BR Repo
"Get all Backup Repositories to filter Selected..."
[String] $URL = "https://" + $ServerFQDN + ":9398/api/repositories?format=Entity"
$BRRepos = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$BRReposXML = Invoke-RestMethod @BRRepos -ErrorAction Stop
$BRReposXML.Repositories.Repository | Select-Object Name, UID, Kind, Capacity, FreeSpace | Format-Table -AutoSize
"Get Backup Repository..."
foreach ($Repo in $BRReposXML.Repositories.Repository) {
if ($Repo.name -eq $RepoName) {$RepoXML = $Repo}
}
if (!($RepoXML)) {
Throw "No Repository with name '$RepoName' found!"
}
$RepoXML | Select-Object Name, UID, Kind, Capacity, FreeSpace | Format-Table -AutoSize
$BRRepoUID = $RepoXML.uid
#endregion
#region: POST - Add vCloud Org
"Create vCloud Org..."
[String] $URL = "https://" + $ServerFQDN + ":9398/api/vCloud/orgConfigs"
$VCloudOrganizationConfigCreate = @{uri = $URL;
Method = 'POST';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId'];
'Content-Type' = 'application/xml'}
Body = @"
<?xml version="1.0" encoding="utf-8"?>
<VCloudOrganizationConfigCreateSpec xmlns="http://www.veeam.com/ent/v1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OrganizationName>$OrgName</OrganizationName>
<BackupServerUid>$BRServerUID</BackupServerUid>
<RepositoryUid>$BRRepoUID</RepositoryUid>
<QuotaGb>$RepoQuota</QuotaGb>
<TemplateJobUid>$BRJobUID</TemplateJobUid>
<JobSchedulerType>Full</JobSchedulerType>
</VCloudOrganizationConfigCreateSpec>
"@
}
$VCloudOrganizationConfigCreateXML = Invoke-RestMethod @VCloudOrganizationConfigCreate
#endregion
#region: GET - Get vCloud Org
Start-Sleep 5
"Get all vCloud Orgs..."
[String] $URL = "https://" + $ServerFQDN + ":9398/api/vCloud/orgConfigs?format=Entity"
$VCloudOrganizationConfig = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$VCloudOrganizationConfigXML = Invoke-RestMethod @VCloudOrganizationConfig
$VCloudOrganizationConfigXML.VCloudOrganizationConfigs.VCloudOrganizationConfig | Select-Object Name, UID, QuotaGb | Format-Table -AutoSize
#endregion
}
process {
}
end {
}
}
[String] $Server = "<Veeam ent. Manager IP / name>"
[Boolean] $HTTPS = $True
[String] $Port = "9398"
[PSCredential] $Credential = Get-Credential
[String] $Org = "<Your vCloud Director Org>"
[String] $JobTemplateName = "<Your Job name>"
[String] $RepoName = "<Your Repository name>"
[Long] $Quota = 500
#region: Workaround for SelfSigned Cert
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
#endregion
#region: Switch Http/s
if ($HTTPS -eq $True) {$Proto = "https"} else {$Proto = "http"}
#endregion
#region: POST - Authorization
[String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/sessionMngr/?v=latest"
Write-Verbose "Authorization Url: $URL"
$Auth = @{uri = $URL;
Method = 'POST';
}
$AuthXML = Invoke-WebRequest @Auth -ErrorAction Stop -Credential $Credential
#endregion
#region: GET - Get BR Server
"`nGet All Registered Veeam Server..."
[String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/backupServers?format=Entity"
Write-Verbose "Get BR Server Url: $URL"
$BRServer = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$BRServerXML = Invoke-RestMethod @BRServer -ErrorAction Stop
$BRServerXML.BackupServers.BackupServer | select Name, UID, Port, Version
$BRServerUID = $BRServerXML.BackupServers.BackupServer.UID
#endregion
#region: GET - Get BR Template Job
"`nGet all Backup Jobs to filter Template..."
[String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/jobs?format=Entity"
$BRJobs = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$BRJobsXML = Invoke-RestMethod @BRJobs -ErrorAction Stop
$BRJobsXML.Jobs.Job | select Name, UID, Platform | ft -AutoSize
foreach ($Job in $BRJobsXML.Jobs.job) {
if ($job.name -eq $JobTemplateName) {$JobTemplateXML = $Job}
}
$BRJobUID = $JobTemplateXML.uid
#endregion
#region: GET - Get BR Repo
"`nGet all Backup Repositories to filter Selected..."
[String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/repositories?format=Entity"
$BRRepos = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$BRReposXML = Invoke-RestMethod @BRRepos -ErrorAction Stop
$BRReposXML.Repositories.Repository | select Name, UID, Kind
foreach ($Repo in $BRReposXML.Repositories.Repository) {
if ($Repo.name -eq $RepoName) {$RepoXML = $Repo}
}
$BRRepoUID = $RepoXML.uid
#endregion
#region: POST - Add vCloud Org
"`nCreate vCloud Org..."
[String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/vCloud/orgConfigs"
$VCloudOrganizationConfigCreate = @{uri = $URL;
Method = 'POST';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId'];
'Content-Type' = 'application/xml'}
Body = @"
<VCloudOrganizationConfigCreateSpec xmlns="http://www.veeam.com/ent/v1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<OrganizationName>$org</OrganizationName>
<BackupServerUid>$BRServerUID</BackupServerUid>
<RepositoryUid>$BRRepoUID</RepositoryUid>
<QuotaGb>$Quota</QuotaGb>
<TemplateJobUid>$BRJobUID</TemplateJobUid>
<JobSchedulerType>Full</JobSchedulerType>
</VCloudOrganizationConfigCreateSpec>
"@
}
$VCloudOrganizationConfigCreateXML = Invoke-RestMethod @VCloudOrganizationConfigCreate -ErrorAction Stop
#endregion
#region: GET - Get vCloud Org
"`nGet all vCloud Org`s..."
[String] $URL = $Proto + "://" + $Server + ":" + $Port + "/api/vCloud/orgConfigs?format=Entity"
$VCloudOrganizationConfig = @{uri = $URL;
Method = 'GET';
Headers = @{'X-RestSvcSessionId' = $AuthXML.Headers['X-RestSvcSessionId']}
}
$VCloudOrganizationConfigXML = Invoke-RestMethod @VCloudOrganizationConfig -ErrorAction Stop
$VCloudOrganizationConfigXML.VCloudOrganizationConfigs.VCloudOrganizationConfig | select Name, UID, QuotaGb | ft -AutoSize
#endregion
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.