Managing Altaro VM Backup with PowerShell

Recently, I decided to try to determine if there was a way to manage Altaro VM Backup with PowerShell. I figured there must be some database, files, or something that I could at least query with PowerShell.

What I found is Altaro has a RESTful API and they have numerous PowerShell scripts for working with it. In Altaro version 7, there are 33 PowerShell scripts located in the “C:\Program Files\Altaro\Altaro Backup\Cmdlets” folder if you took the defaults during the installation, otherwise they’re wherever you installed Altaro. Altaro has a blog article on their website announcing the API in March of 2016.

After taking a look at Altaro’s PowerShell scripts, I decided not to use them. I started writing my own PowerShell module with functions for working with their API.

Although their API has a limitation that it only works locally on the actual Altaro VM Backup server, that doesn’t mean that you can’t use it with PowerShell remoting. Working remotely is always better from a manageability standpoint since using remote desktop to connect to the server only to run PowerShell on it locally defeats the whole purpose of using PowerShell.

I’ll start out by storing my credentials in a variable named Cred:

$Cred = Get-Credential

Use one-to-one remoting to access my Altaro VM Backup server:

Enter-PSSession -ComputerName mr101 -Credential $Cred

The Altaro API service is disabled by default. Set it to start automatically and then start the service:

Get-Service -DisplayName 'Altaro VM Backup API Service' |
Set-Service -StartupType Automatic -PassThru |
Start-Service -PassThru

altaro-api9b.png

The Start-MrAltaroSession function shown in the following code example is used to start a session with the API on an Altaro VM Backup server:

#Requires -Version 3.0
function Start-MrAltaroSession {

<#
.SYNOPSIS
    Starts a new session with the RESTful API of an Altaro VM Backup server.

.DESCRIPTION
    Start-MrAltaroSession is an advanced function that starts a new session with the RESTful API of an
    Altaro VM Backup server. In it current interation, the Altaro RESTful API can only be used locally
    on the Altaro VM Backup server.

.PARAMETER ComputerName
    Name of the Altaro VM Backup server. The default is localhost. Currently, the Altaro API only works
    with localhost. $env:COMPUTERNAME or the actual computer name does not work.

.PARAMETER Port
    Port number that the Altaro VM Backup API is listening on. The default is 35113.

.PARAMETER Credential
    The credentials for connecting to the Altaro VM Backup API.

.EXAMPLE
     Start-MrAltaroSession -Credential (Get-Credential)

.EXAMPLE
     Start-MrAltaroSession -ComputerName localhost -Credential (Get-Credential)

.EXAMPLE
     Start-MrAltaroSession -ComputerName localhost -Port 35113 -Credential (Get-Credential)

.INPUTS
    None

.OUTPUTS
    PSCustomObject

.NOTES
    Author:  Mike F Robbins
    Website: http://mikefrobbins.com
    Twitter: @mikefrobbins
#>

    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [Alias('ServerName')]
        [string]$ComputerName = 'localhost',

        [ValidateNotNullOrEmpty()]
        [int]$Port = 35113,

        [Parameter(Mandatory)]
        [System.Management.Automation.Credential()]$Credential
    )

    $Uri = "http://$ComputerName`:$Port/api/sessions/start"

    $Body = @{
        ServerAddress = $ComputerName
        ServerPort = '35107'
        Username = $Credential.UserName -replace '^.*\\'
        Password = $Credential.GetNetworkCredential().Password
        Domain = $Credential.UserName -replace '\\.*$'
    } | ConvertTo-Json

    try {
        $Results =  Invoke-RestMethod -Uri $uri -Method Post -ContentType 'application/json' -Body $Body
    }
    catch {
        Write-Error -Message "Unable to connect to Altaro API at: $Uri"
    }

    if ($Results.Success -eq $true) {
        [PSCustomObject]@{
            SessionId = [guid]$Results.Data
        }
    }
    elseif ($Results.Success -eq $false) {
        Write-Error -Message "$($Results.ErrorMessage). Error Code: $($Results.ErrorCode). $($Results.ErrorAdditionalDetails)"
    }
}

From this point forward, I can use the Using variable scope modifier with the credentials I stored in the local variable named Cred on the remote server.

Use the Start-MrAltaroSession function to start a new session with the API:

Start-MrAltaroSession -Credential $Using:Cred

altaro-api1b.png

Errors are returned as an actual error:

Start-MrAltaroSession -Credential $Using:Cred

altaro-api2b.png

The Get-MrAltaroOperationStatus function is used to retrieve the status of operations that are currently running:

#Requires -Version 3.0
function Get-MrAltaroOperationStatus {

<#
.SYNOPSIS
    Retrieves the status and progress for Altaro VM Backup jobs which are currently running.

.DESCRIPTION
    Get-MrAltaroOperationStatus is an advanced function that retrieves the status and progress for Altaro
    VM Backup jobs (backups, offsite copies, restores, seed to disks) which are currently running.

.PARAMETER ComputerName
    Name of the Altaro VM Backup server. The default is localhost. Currently, the Altaro API only works
    with localhost. $env:COMPUTERNAME or the actual computer name does not work.

.PARAMETER Port
    Port number that the Altaro VM Backup API is listening on. The default is 35113.

.PARAMETER SessionId
    The Id in the form of a GUID for the sesison created by Start-MrAltaroSession.

.PARAMETER OperationId
    The Id in the form of a GUID for the specific operation to return results for.

.EXAMPLE
     Get-MrAltaroOperationStatus -SessionId b3019809-cfbe-4ac6-93df-a24c91b5b28e

.EXAMPLE
     Get-MrAltaroOperationStatus -SessionId b3019809-cfbe-4ac6-93df-a24c91b5b28e -OperationId 1351d928-0391-4a45-8d5a-ae4b806bea66

.EXAMPLE
     Get-MrAltaroOperationStatus -ComputerName localhost -Port 35113 -SessionId b3019809-cfbe-4ac6-93df-a24c91b5b28e

.INPUTS
    Guid

.OUTPUTS
    PSCustomObject

.NOTES
    Author:  Mike F Robbins
    Website: http://mikefrobbins.com
    Twitter: @mikefrobbins
#>

    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [Alias('ServerName')]
        [string]$ComputerName = 'localhost',

        [ValidateNotNullOrEmpty()]
        [int]$Port = 35113,

        [Parameter(Mandatory,
                   ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [guid]$SessionId,

        [guid]$OperationId
    )

    PROCESS {
        $uri = "http://$ComputerName`:$Port/api/activity/operation-status/$SessionId"

        Invoke-RestMethod -Uri $uri -Method Get -ContentType 'application/json' |
        Select-Object -ExpandProperty Statuses
    }

}

These include backups, offsite copies, restores, and seed to disks operations:

Get-MrAltaroOperationStatus -SessionId fe0a7c65-1fab-474c-bf2f-4a2a2f8f2b89

altaro-api3b.png

You can also pipe Start-MrAltaroSession directly to Get-MrAltaroOperationStatus:

Start-MrAltaroSession -Credential $Using:Cred | Get-MrAltaroOperationStatus

altaro-api4b.png

The Stop-MrAltaroSession function gracefully closes out of one or more sessions that were previously opened:

#Requires -Version 3.0
function Stop-MrAltaroSession {

<#
.SYNOPSIS
    Stops one or more sessions with the RESTful API of an Altaro VM Backup server.

.DESCRIPTION
    Stop-MrAltaroSession is an advanced function that stops one or more sessions with the RESTful API of
    an Altaro VM Backup server. In it current interation, the Altaro RESTful API can only be used locally
    on the Altaro VM Backup server.

.PARAMETER ComputerName
    Name of the Altaro VM Backup server. The default is localhost. Currently, the Altaro API only works
    with localhost. $env:COMPUTERNAME or the actual computer name does not work.

.PARAMETER Port
    Port number that the Altaro VM Backup API is listening on. The default is 35113.

.PARAMETER SessionId
    The Id in the form of a GUID for the sesison created by Start-MrAltaroSession.

.EXAMPLE
     Stop-MrAltaroSession

.EXAMPLE
     Stop-MrAltaroSession -SessionId 6d2d22ef-06df-4bb0-976b-bb6a8b3f2683

.EXAMPLE
     Stop-MrAltaroSession -ComputerName localhost -Port 35113 -SessionId 66c09e7d-e10c-4608-b9cd-d35579784e70

.INPUTS
    None

.OUTPUTS
    PSCustomObject

.NOTES
    Author:  Mike F Robbins
    Website: http://mikefrobbins.com
    Twitter: @mikefrobbins
#>

    [CmdletBinding()]
    param (
        [ValidateNotNullOrEmpty()]
        [Alias('ServerName')]
        [string]$ComputerName = 'localhost',

        [ValidateNotNullOrEmpty()]
        [int]$Port = 35113,

        [Parameter(ValueFromPipeline,
                   ValueFromPipelineByPropertyName)]
        [guid]$SessionId
    )

    PROCESS {
        $uri = "http://$ComputerName`:$Port/api/sessions/end"

        if ($PSBoundParameters.SessionId){
            $uri = "$uri/$SessionId"
        }

        try {
            $Results =  Invoke-RestMethod -Uri $uri -Method Post -ContentType 'application/json'
        }
        catch {
            Write-Error -Message "Unable to connect to Altaro API at: $Uri"
        }

        if ($Results.Success -eq $true -and $Results.ClosedSessions.SessionToken -ne $null) {
            foreach ($Result in $Results.ClosedSessions) {
                [PSCustomObject]@{
                    SessionId = [guid]$Result.SessionToken
                }
            }
        }
        elseif ($Results.Success -eq $true -and $Results.ClosedSessions.SessionToken -eq $null){
            Write-Warning -Message 'There are no open sessions.'
        }
        elseif ($Results.Success -eq $false) {
            Write-Error -Message "$($Results.ErrorMessage). Error Code: $($Results.ErrorCode). $($Results.ErrorAdditionalDetails)"
        }
    }

}

It can be used to stop a single session. If multiple sessions existed, the SessionId parameter could be specified to stop a single session.

Stop-MrAltaroSession

altaro-api5b.png

By default, if multiple sessions exist, it stops all of them:

Stop-MrAltaroSession

altaro-api6b.png

A warning is returned if no sessions exist:

Stop-MrAltaroSession

altaro-api7b.png

The functions shown in this blog article are part of my MrAltaro PowerShell script module which can be downloaded from my Altaro repository on GitHub.

For more information about the Altaro RESTful API, see their documentation page.

µ