Sample backup script
As an alternative to using
from the appliance UI, you can write and run a script to automatically create and download an appliance backup file.The Sample backup.ps1 script shown below provides a sample PowerShell script that uses REST calls to create and download an appliance backup file. Cut and paste this sample script into a file on a Windows system that runs PowerShell version 3.0, and edit the script to customize it for your environment.
You can schedule the backup script to run automatically in interactive or batch mode on a regular basis (Hewlett Packard Enterprise recommends daily backups). Only a user with Backup administrator or Infrastructure administrator privileges can run the script interactively.
To run the script interactively, do not include any parameters. The script prompts you to enter the appliance host name, appliance user name and password, and the name of a file to store these parameters for batch mode executions. Enter the name and password of a user with the Backup administrator or Infrastructure administrator role. The user name and password are stored encrypted.
Hewlett Packard Enterprise recommends that you run the script interactively the first time. Then, you can schedule the script to run automatically in the background using the parameter file created by the first run.
To run the script in batch mode, specify the name of the file containing the parameters on the command line.
Hewlett Packard Enterprise recommends that you install cURL with the SSL option to improve performance. The sample script works without cURL, but it might take several hours to download a large backup file. To download cURL, see:
http://curl.haxx.se/download.html
You might also need to install Microsoft Visual C++ Redistributable, the
MSVCR100.dll
file, available here:
64 bit: http://www.microsoft.com/download/en/details.aspx?id=14632
32 bit: http://www.microsoft.com/download/en/details.aspx?id=5555
Make sure the path environment variable includes the path for cURL.
Sample script
The sample script makes the following calls to create and download a backup file:
Calls
queryfor-credentials()
to get the appliance host name, user name, and password by either prompting the user or reading the values from a file.Calls
login-appliance()
to issue a REST request to obtain a session ID used to authorize backup REST calls.Calls
backup-appliance()
to issue a REST request to start a backup.Calls
waitFor-completion()
to issue REST requests to poll for backup status until the backup completes.Calls
get-backupResource()
to issue a REST request to get the download URI.Calls
download-backup()
to issue a REST request to download the backup.
Sample backup.ps1 script
# (C) Copyright 2012-2014 Hewlett Packard Enterprise Development LP
###########################################################################################################################
# Name: backup.ps1
# Usage: {directory}\backup.ps1 or {directory}\backup.ps1 filepath
# Parameter: $filepath: optional, uses the file in that path as the login credentials. ie: host address, username,
# password, and, optionally, the Active Directory domain name
# Purpose: Runs the backup function on the appliance and downloads it onto your machine's drive
# in current user's home directory
# Notes: To improve performance, this script uses the curl command if it is installed. The curl command must
# be installed with the SSL option.
# Windows PowerShell 3.0 must be installed to run the script
###########################################################################################################################
#tells the computer that this is a trusted source that we are connecting to (brute force, could be refined)
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }
$global:interactiveMode = 0
# The scriptApiVersion is the default Api version (if the appliance supports this level
# or higher). This variable may be changed if the appliance is at a lower Api level.
$global:scriptApiVersion = 3
# Using this Api version or greater requires a different interaction when creating a backup.
Set-Variable taskResourceV2ApiVersion -option Constant -value 3
try {
#this log must be added if not already on your computer
New-EventLog -LogName Application -Source backup.ps1 -ErrorAction stop
}
catch [System.Exception]
{
#this is just to keep the error "already a script" from showing up on the screen if it is already created
}
##### Querying user for login info #####
function queryfor-credentials ()
{
<#
.DESCRIPTION
Gathers information from User if in manual entry mode (script ran with zero arguments) or
runs silently and gathers info from specified path (script ran with 1 argument)
.INPUTS
None, this function does not take inputs.
.OUTPUTS
Returns an object that contains the login name, password, hostname and
ActiveDirectory domain to connect to.
.EXAMPLE
$variable = queryfor-credentials #runs function, saves json object to variable.
#>
if ($args[0] -eq $null)
{
Write-Host "Enter appliance name (https://ipaddress)"
$appliance = Read-Host
# Correct some common errors
$appliance = $appliance.Trim().ToLower()
if (!$appliance.StartsWith("https://"))
{
if ($appliance.StartsWith("http://"))
{
$appliance = $appliance.Replace("http","https")
} else {
$appliance = "https://" + $appliance
}
}
Write-Host "Enter username"
$username = Read-Host -AsSecureString | ConvertFrom-SecureString
Write-Host "Enter password"
$SecurePassword = Read-Host -AsSecureString | ConvertFrom-SecureString
Write-Host "If using Active Directory, enter the Active Directory domain"
Write-Host " (Leave this field blank if not using Active Directory.)"
$ADName = Read-Host
Write-Host "Would you like to save these credentials to a file? (username and password encrypted)"
$saveQuery = Read-Host
$loginVals = [pscustomobject]@{ userName = $username; password = $SecurePassword;
hostname = $appliance; authLoginDomain = $ADName }
$loginJson = $loginVals | convertTo-json
$global:interactiveMode = 1
if ($saveQuery[0] -eq "y") #enters into the mode to save the credentials
{
Write-Host "Enter file path and file name to save credentials (example: C:\users\bob\machine1.txt)"
$storagepath = Read-Host
try
{
$loginJson | Out-File $storagepath -NoClobber -ErrorAction stop
}
catch [System.Exception]
{
Write-Host $_.Exception.message
if ($_.Exception.getType() -eq [System.IO.IOException]) # file already exists throws an IO exception
{
do
{
Write-Host "Overwrite existing credentials for this machine?"
[string]$overwriteQuery = Read-Host
if ($overwriteQuery[0] -eq 'y')
{
$loginJson | Out-File $storagepath -ErrorAction stop
$exitquery = 1
}
elseif ($overwriteQuery[0] -eq 'n')
{
$exitquery = 1
}
else
{
Write-Host "Please respond with a y or n"
$exitquery = 0
}
} while ($exitquery -eq 0)
}
else
{
Write-Host "Improper filepath or no permission to write to given directory"
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Improper filepath, $storagepath " $_.Exception.message
return
}
}
$savedLoginJson = Get-Content $storagepath
Write-Host "Run backup?"
$continue = 0
do
{
$earlyExit = Read-Host
if ($earlyExit[0] -eq 'n')
{
return
}
elseif ($earlyExit[0] -ne 'y')
{
Write-Host "Please respond with a y or n"
}
else
{
$continue = 1
}
} while ($continue -eq 0)
}
else
{
return $loginJson
}
}
elseif ($args.count -ne 1)
{
Write-Host "Incorrect number of arguments, use either filepath parameter or no parameters."
return
}
else
{
foreach ($arg in $args)
{
$storagepath = $arg
}
try
{
$savedLoginJson = Get-Content $storagepath -ErrorAction stop
}
catch [System.Exception]
{
Write-Host "Login credential file not found. Please run script without arguments to access manual entry mode."
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Login credential file not found. Please run script without arguments to access manual entry mode."
return
}
}
return $savedloginJson
}
##### getApiVersion: Get X_API_Version #####
function getApiVersion ([int32] $currentApiVersion,[string]$hostname)
{
<#
.DESCRIPTION
Sends a web request to the appliance to obtain the current Api version.
Returns the lower of: Api version supported by the script and Api version
supported by the appliance.
.PARAMETER currentApiVersion
Api version that the script is currently using
.PARAMETER hostname
The appliance address to send the request to (in https://{ipaddress} format)
.INPUTS
None, does not accept piping
.OUTPUTS
Outputs the new active Api version
.EXAMPLE
$global:scriptApiVersion = getApiVersion()
#>
# the particular Uri on the Appliance to reqest the Api Version
$versionUri = "/rest/version"
# append the Uri to the end of the IP address to obtain a full Uri
$fullVersionUri = $hostname + $versionUri
# use setup-request to issue the REST request api version and get the response
try
{
$applianceVersionJson = setup-request -Uri $fullVersionUri -method "GET" -accept "application/json" -contentType "application/json"
if ($applianceVersionJson -ne $null)
{
$applianceVersion = $applianceVersionJson | convertFrom-Json
$currentApplianceVersion = $applianceVersion.currentVersion
if ($currentApplianceVersion -lt $currentApiVersion)
{
return $currentApplianceVersion
}
return $currentApiVersion
}
}
catch [System.Exception]
{
if ($global:interactiveMode -eq 1)
{
Write-Host $error[0].Exception.Message
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $error[0].Exception.Message
}
}
}
##### Sending login info #####
function login-appliance ([string]$username,[string]$password,[string]$hostname,[string]$ADName)
{
<#
.DESCRIPTION
Attempts to send a web request to the appliance and obtain an authorized sessionID.
.PARAMETER username
The username to log into the remote appliance
.PARAMETER password
The correct password associated with username
.PARAMETER hostname
The appliance address to send the request to (in https://{ipaddress} format)
.PARAMETER ADName
The Active Directory name (optional)
.INPUTS
None, does not accept piping
.OUTPUTS
Outputs the response body containing the needed session ID.
.EXAMPLE
$authtoken = login-appliance $username $password $hostname $ADName
#>
# the particular Uri on the Appliance to reqest an "auth token"
$loginUri = "/rest/login-sessions"
# append the Uri to the end of the IP address to obtain a full Uri
$fullLoginUri = $hostname + $loginUri
# create the request body as a hash table, then convert it to json format
if ($ADName)
{
$body = @{ userName = $username; password = $password; authLoginDomain = $ADName } | convertTo-json
}
else # null or empty
{
$body = @{ userName = $username; password = $password } | convertTo-json
}
# use setup-request to issue the REST request to login and get the response
try
{
$loginResponse = setup-request -Uri $fullLoginUri -method "POST" -accept "application/json" -contentType "application/json" -Body $body
if ($loginResponse -ne $null)
{
$loginResponse | convertFrom-Json
}
}
catch [System.Exception]
{
if ($global:interactiveMode -eq 1)
{
Write-Host $error[0].Exception.Message
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $error[0].Exception.Message
}
}
}
##### Executing backup ######
function backup-Appliance ([string]$authValue,[string]$hostname)
{
<#
.DESCRIPTION
Gives the appliance the command to start creating a backup
.PARAMETER authValue
The authorized sessionID given by login-appliance
.PARAMETER hostname
The location of the appliance to connect to (in https://{ipaddress} format)
.INPUTS
None, does not accept piping
.OUTPUTS
The task Resource returned by the appliance, converted to a hashtable object
.EXAMPLE
$taskResource = backup-Appliance $sessionID $hostname
#>
# append the REST Uri for backup to the IP address of the Appliance
$bkupUri = "/rest/backups/"
$fullBackupUri = $hostname + $bkupUri
# create a new webrequest and add the proper headers (new header, auth, is needed for authorization
# in all functions from this point on)
try
{
if ($global:scriptApiVersion -lt $taskResourceV2ApiVersion)
{
$taskResourceJson = setup-request -Uri $fullBackupUri -method "POST" -accept "application/json" -contentType "application/json" -authValue $authValue
}
else
{
$taskUri = setup-request -Uri $fullBackupUri -method "POST" -accept "application/json" -contentType "application/json" -authValue $authValue -returnLocation $true
if ($taskUri -ne $null)
{
$taskResourceJson = setup-request -Uri $taskUri -method "GET" -accept "application/json" -contentType "application/json" -authValue $authValue
}
}
if ($taskResourceJson -ne $null)
{
return $taskResourceJson | ConvertFrom-Json
}
}
catch [System.Exception]
{
if ($global:interactiveMode -eq 1)
{
Write-Host $error[0].Exception.Message
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $error[0].Exception.Message
}
}
}
##### Polling to see if backup is finished ######
function waitFor-completion ([object]$taskResource,[string]$authValue,[string]$hostname)
{
<#
.DESCRIPTION
Checks the status of the backup every twenty seconds, stops when status changes from running to a different status
.PARAMETER taskResource
The response object from the backup-appliance method
.PARAMETER authValue
The authorized session ID
.PARAMETER hostname
The appliance to connect to (in https://{ipaddress} format)
.INPUTS
None, does not accept piping
.OUTPUTS
The new task resource object, which contains the Uri to get the backup resource in the next function
.EXAMPLE
$taskResource = waitFor-Completion $taskResource $sessionID $hostname
#>
# extracts the Uri of the task Resource from itself, to poll repeatedly
$taskResourceUri = $taskResource.uri
if ($taskResourceUri -eq $null)
{
# Caller will provide the error message
return
}
# appends the Uri to the hostname to create a fully-qualified Uri
$fullTaskUri = $hostname + $taskResourceUri
# retries if unable to get backup progress information
$errorCount = 0
$errorMessage = ""
if ($global:interactiveMode -eq 1)
{
Write-Host "Backup initiated."
Write-Host "Checking for backup completion, this may take a while."
}
# a while loop to determine when the backup process is finished
do
{
try
{
# creates a new webrequest with appropriate headers
$taskResourceJson = setup-request -Uri $fullTaskUri -method "GET" -accept "application/json" -authValue $authValue -isSilent $true
# converts the response from the Appliance into a hash table
$taskResource = $taskResourceJson | convertFrom-Json
# checks the status of the task manager
$status = $taskResource.taskState
}
catch
{
$errorMessage = $error[0].Exception.Message
$errorCount = $errorCount + 1
$status = "RequestFailed"
Start-Sleep -s 15
continue
}
# Update progress bar
if ($global:interactiveMode -eq 1)
{
$trimmedPercent = ($taskResource.completedSteps) / 5
$progressBar = "[" + "=" * $trimmedPercent + " " * (20 - $trimmedPercent) + "]"
Write-Host "`r Backup progress: $progressBar " $taskResource.completedSteps "%" -NoNewline
}
# Reset the error count since progress information was successfully retrieved
$errorCount = 0
# If the backup is still running, wait a bit, and then check again
if ($status -eq "Running")
{
Start-Sleep -s 20
}
} while (($status -eq "Running" -or $status -eq "RequestFailed") -and $errorCount -lt 20);
# if the backup reported an abnormal state, report the state and exit function
if ($status -ne "Completed")
{
if ($global:interactiveMode -eq 1)
{
Write-Host "`n"
Write-Host "Backup stopped abnormally"
Write-Host $errorMessage
}
else
{
#log error message
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Backup stopped abnormally"
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $errorMessage
}
return $null
}
# upon successful completion of task, outputs a hash table which contains task resource
else
{
Write-Host "`n"
$taskResource
return
}
}
##### Gets the backup resource #####
function get-backupResource ([object]$taskResource,[string]$authValue,[string]$hostname)
{
<#
.DESCRIPTION
Gets the Uri for the backup resource from the task resource and gets the backup resource
.PARAMETER taskResource
The task resource object that we use to get the Uri for the backup resource
.PARAMETER authValue
The authorized sessionID
.PARAMETER hostname
the appliance to connect to (in https://{ipaddress} format)
.INPUTS
None, does not accept piping
.OUTPUTS
The backup resource object
.EXAMPLE
$backupResource = get-BackupResource $taskResource $sessionID $applianceName
#>
# the backup Resource Uri is extracted from the task resource
if ($global:scriptApiVersion -lt $taskResourceV2ApiVersion)
{
$backupUri = $taskResource.associatedResourceUri
}
else
{
$backupUri = $taskResource.associatedResource.resourceUri
}
if ($backupUri -eq $null)
{
# Caller will provide the error message
return
}
# construct the full backup Resource Uri from the hostname and the backup resource uri
$fullBackupUri = $hostname + $backupUri
# get the backup resource that contains the Uri for downloading
try
{
# creates a new webrequest with appropriate headers
$backupResourceJson = setup-request -Uri $fullBackupUri -method "GET" -accept "application/json" -auth $authValue
if ($backupResourceJson -ne $null)
{
$resource = $backupResourceJson | convertFrom-Json
if ($global:interactiveMode -eq 1)
{
Write-Host "Obtained backup resource. Now downloading. This may take a while ..."
}
$resource
return
}
}
catch [System.Exception]
{
if ($global:interactiveMode -eq 1)
{
Write-Host $error[0].Exception.Message
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $error[0].Exception.Message
}
}
}
##### Function to download the backup file #####
function download-Backup ([PSCustomObject]$backupResource,[string]$authValue,[string]$hostname)
{
<#
.DESCRIPTION
Downloads the backup file from the appliance to the local system. Tries to use the
curl command. The curl command has significantly better performance especially for
large backups. If curl isn't installed, invokes download-Backup-without-curl to
download the backup.
.PARAMETER backupResource
Backup resource containing Uri for downloading
.PARAMETER authValue
The authorized sessionID
.PARAMETER hostname
The IP address of the appliance
.INPUTS
None, does not accept piping
.OUTPUTS
The absolute path of the download file
.EXAMPLE
download-backup $backupResource $sessionID https://11.111.11.111
#>
$downloadUri = $hostname + $backupResource.downloadUri
$fileDir = [environment]::GetFolderPath("Personal")
$filePath = $fileDir + "\" + $backupResource.id + ".bkp"
$curlDownloadCommand = "curl -o " + $filePath + " -s -f -L -k -X GET " +
"-H 'accept: application/octet-stream' " +
"-H 'auth: " + $authValue + "' " +
"-H 'X-API-Version: $global:scriptApiVersion' " +
$downloadUri
$curlGetDownloadErrorCommand = "curl -s -k -X GET " +
"-H 'accept: application/json' " +
"-H 'auth: " + $authValue + "' " +
"-H 'X-API-Version: $global:scriptApiVersion' " +
$downloadUri
try
{
$testCurlSslOption = curl -V
if ($testCurlSslOption -match "SSL")
{
invoke-expression $curlDownloadCommand
}
else
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Version of curl must support SSL to get improved download performance."
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Version of curl must support SSL to get improved download performance"
}
return download-Backup-without-curl $backupResource $authValue $hostname
}
if ($LASTEXITCODE -ne 0)
{
$errorResponse = invoke-expression $curlGetDownloadErrorCommand
if ($global:interactiveMode -eq 1)
{
Write-Host "Download using curl error: $errorResponse"
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Download error: $errorResponse"
}
if (Test-Path $filePath)
{
Remove-Item $filePath
}
return
}
if ($global:interactiveMode -eq 1)
{
Write-Host "Backup download complete!"
}
}
catch [System.Management.Automation.CommandNotFoundException]
{
return download-Backup-without-curl $backupResource $authValue $hostname
}
catch [System.Exception]
{
Write-Host "Not able to download backup"
Write-Host $error[0].Exception
return
}
return $filePath
}
##### Function to download the Backup file without using the curl command #####
function download-Backup-without-curl ([PSCustomObject]$backupResource,[string]$authValue,[string]$hostname)
{
<#
.DESCRIPTION
Downloads the backup file from the appliance to the local system (without using curl)
.PARAMETER backupResource
Backup resource containing Uri for downloading
.PARAMETER authValue
The authorized sessionID
.PARAMETER hostname
The IP address of the appliance
.INPUTS
None, does not accept piping
.OUTPUTS
The absolute path of the download file
.EXAMPLE
download-backup-without-curl $backupResource $sessionID https://11.111.11.111
#>
# appends Uri ( obtained from previous function) to IP address
$downloadUri = $hostname + $backupResource.downloadUri
$downloadTimeout = 43200000 # 12 hours
$bufferSize = 65536 # bytes
# creates a new webrequest with appropriate headers
[net.httpsWebRequest]$downloadRequest = [net.webRequest]::create($downloadUri)
$downloadRequest.method = "GET"
$downloadRequest.AllowAutoRedirect = $TRUE
$downloadRequest.Timeout = $downloadTimeout
$downloadRequest.ReadWriteTimeout = $downloadTimeout
$downloadRequest.Headers.Add("auth", $authValue)
$downloadRequest.Headers.Add("X-API-Version", $global:scriptApiVersion)
# accept either octet-stream or json to allow the response body to contain either the backup or an exception
$downloadRequest.accept = "application/octet-stream;q=0.8,application/json"
# creates a variable that stores the path to the file location. Note: users may change this to other file paths.
$fileDir = [environment]::GetFolderPath("Personal")
try
{
# connects to the Appliance, creates a new file with the content of the response
[net.httpsWebResponse]$response = $downloadRequest.getResponse()
$responseStream = $response.getResponseStream()
$responseStream.ReadTimeout = $downloadTimeout
#saves file as the name given by the backup ID
$filePath = $fileDir + "\" + $backupResource.id + ".bkp"
$sr = New-Object System.IO.FileStream ($filePath,[System.IO.FileMode]::create)
$responseStream.CopyTo($sr,$bufferSize)
$response.close()
$sr.close()
if ($global:interactiveMode -eq 1)
{
Write-Host "Backup download complete!"
}
}
catch [Net.WebException]
{
$errorMessage = $error[0].Exception.message
#Try to get more information about the error
try {
$errorResponse = $error[0].Exception.InnerException.Response.getResponseStream()
$sr = New-Object IO.StreamReader ($errorResponse)
$rawErrorStream = $sr.readtoend()
$error[0].Exception.InnerException.Response.close()
$errorObject = $rawErrorStream | convertFrom-Json
if (($errorObject.message.length -gt 0) -and
($errorObject.recommendedActions.length -gt 0))
{
$errorMessage = $errorObject.message + " " + $errorObject.recommendedActions
}
}
catch [System.Exception]
{
#Use exception message
}
if ($global:interactiveMode -eq 1)
{
Write-Host $errorMessage
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $errorMessage
}
return
}
return $filePath
}
function setup-request ([string]$uri,[string]$method,[string]$accept,[string]$contentType = "",[string]$authValue = "",[object]$body = $null,[bool]$isSilent=$false, [bool]$returnLocation=$false)
{
try
{
[net.httpsWebRequest]$request = [net.webRequest]::create($uri)
$request.method = $method
$request.accept = $accept
$request.Headers.Add("Accept-Language: en-US")
if ($contentType -ne "")
{
$request.ContentType = $contentType
}
if ($authValue -ne "")
{
$request.Headers.Item("auth") = $authValue
}
$request.Headers.Item("X-API-Version") = $global:scriptApiVersion
if ($body -ne $null)
{
$requestBodyStream = New-Object IO.StreamWriter $request.getRequestStream()
$requestBodyStream.WriteLine($body)
$requestBodyStream.flush()
$requestBodyStream.close()
}
# attempt to connect to the Appliance and get a response
[net.httpsWebResponse]$response = $request.getResponse()
if ($returnLocation)
{
$taskUri = $response.getResponseHeader("Location")
$response.close()
return $taskUri
}
else
{
# response stored in a stream
$responseStream = $response.getResponseStream()
$sr = New-Object IO.StreamReader ($responseStream)
#the stream, which contains a json object, is read into the storage variable
$rawResponseContent = $sr.readtoend()
$response.close()
return $rawResponseContent
}
}
catch [Net.WebException]
{
$errorMessage = $error[0].Exception.message
#Try to get more information about the error
try {
$errorResponse = $error[0].Exception.InnerException.Response.getResponseStream()
$sr = New-Object IO.StreamReader ($errorResponse)
$rawErrorStream = $sr.readtoend()
$error[0].Exception.InnerException.Response.close()
$errorObject = $rawErrorStream | convertFrom-Json
if (($errorObject.message.length -gt 0) -and
($errorObject.recommendedActions.length -gt 0))
{
$errorMessage = $errorObject.message + " " + $errorObject.recommendedActions
}
}
catch [System.Exception]
{
#Use exception message
}
if ($isSilent) {
throw $errorMessage
}
elseif ($global:interactiveMode -eq 1)
{
Write-Host $errorMessage
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message $errorMessage
}
#No need to rethrow since already recorded error
return
}
}
##### Start of function calls #####
#gets the credentials from user, either manual entry or from file
$savedLoginJson = queryfor-credentials $args[0]
if ($savedLoginJson -eq $null)
{
#if an error occurs, it has already been logged in the queryfor-credentials function
return
}
#extracts needed information from the credential json
try
{
$savedLoginJson = "[" + $savedLoginJson + "]"
$savedloginVals = $savedLoginJson | convertFrom-Json
$SecStrLoginname = $savedloginVals.userName | ConvertTo-SecureString -ErrorAction stop
$loginname =
[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecStrLoginName))
$hostname = $savedloginVals.hostname
$SecStrPassword = $savedloginVals.password | ConvertTo-SecureString -ErrorAction stop
$password =
[Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecStrpassword))
$adname = $savedloginVals.authLoginDomain
}
catch [System.Exception]
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Failed to get credentials: " + $error[0].Exception.Message
}
else
{
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Failed to get credentials: " + $error[0].Exception.Message
}
}
#determines the active Api version
$global:scriptApiVersion = getApiVersion $global:scriptApiVersion $hostname
if ($global:scriptApiVersion -eq $null)
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Could not determine appliance Api version"
}
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Could not determine appliance Api version"
return
}
#sends the login request to the machine, gets an authorized session ID if successful
$authValue = login-appliance $loginname $password $hostname $adname
if ($authValue -eq $null)
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Failed to receive login session ID."
}
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Failed to receive login session ID."
return
}
#sends the request to start the backup process, returns the taskResource object
$taskResource = backup-Appliance $authValue.sessionID $hostname
if ($taskResource -eq $null)
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Could not initialize backup"
}
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Could not initialize backup"
return
}
#loops to keep checking how far the backup has gone
$taskResource = waitFor-completion $taskResource $authValue.sessionID $hostname
if ($taskResource -eq $null)
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Could not fetch backup status"
}
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Could not fetch backup status"
return
}
#gets the backup resource
$backupResource = get-backupResource $taskResource $authValue.sessionID $hostname
if ($backupResource -eq $null)
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Could not get the Backup Resource"
}
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Could not get the Backup Resource"
return
}
#downloads the backup file to the local drive
$filePath = download-Backup $backupResource $authValue.sessionID $hostname
if ($filePath -eq $null)
{
if ($global:interactiveMode -eq 1)
{
Write-Host "Could not download the backup"
}
Write-EventLog -EventId 100 -LogName Application -Source backup.ps1 -Message "Could not download the backup"
return
}
if ($global:interactiveMode -eq 1)
{
Write-Host "Backup can be found at $filePath"
Write-Host "If you wish to automate this script in the future and re-use login settings currently entered,"
Write-Host "then provide the file path to the saved credentials file when running the script."
Write-Host "ie: " $MyInvocation.MyCommand.Definition " filepath"
}
else
{
Write-Host "Backup completed successfully."
Write-Host "The backup can be found at $filePath."
}
Write-EventLog -EventId 0 -LogName Application -Source backup.ps1 -Message "script completed successfully"