Settings: Backup > Sample backup script |  | next

# Sample backup script

As an alternative to using Settings→Actions→Create backup from the appliance UI, you can write and run a script to automatically create and download an appliance backup file.

Sample backup.ps1 script 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. See the REST API online help for more information about REST APIs.

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

| NOTE: 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:

1. 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.

2. Calls `login-appliance()` to issue a REST request to obtain a session ID used to authorize backup REST calls.

3. Calls `backup-appliance()` to issue a REST request to start a backup.

4. Calls `waitFor-completion()` to issue REST requests to poll for backup status until the backup completes.

5. Calls `get-backupResource()` to issue a REST request to get the download URI.

6. 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"

See also

- Managing the appliance

- Settings: Backup

prev | up | next
Post-restoration tasks | home | Sample restore script

Copyright © 2013, 2016 Hewlett Packard Enterprise Development LP