Commvault REST API and PowerShell

2 minute read

You can use the Commvault Rest API with PowerShell!

Navigate to the public API for Commvault and change the language to PowerShell to get started.

The example below is for creating a Storage Pool. I used the equivalent API functionality in the Command Center to get the JSON. The JSON can be saved and the file run directly via PowerShell via the Invoke-RestMethod. The example below includes the JSON so that variables can replace the hardcoded values. Please, note I removed one of the DDB partitions as the Command Center defaults to two (2) partitions and I only wanted one (1).

The script will prompt for a Commvault user and password with sufficient permissions. You can specify the parameters or enter at the prompt.

# Example: .\CreatePool.ps1 -storagePoolName trout -ddbPath /CV_DiskLibrary/DDB -diskLibPath /CV_DiskLibrary/DATA -mediaAgentName midnight
# force user to provide info if not done at command line
param(
  [Parameter(Mandatory=$true)]
  [string]$storagePoolName,
  [Parameter(Mandatory=$true)]
  [string]$mediaAgentName,
  [Parameter(Mandatory=$true)]
  [string]$ddbPath,
  [Parameter(Mandatory=$true)]
  [string]$diskLibPath
) #end param

# Let's get a token!
$credential = Get-Credential
$username = $credential.UserName
$password = $credential.GetNetworkCredential().password

# password needs to be in base64 format
$password = [System.Text.Encoding]::UTF8.GetBytes($password)
$password = [System.Convert]::ToBase64String($password)

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Accept", "application/json")
$headers.Add("Content-Type", "application/json")
$body = "{`n  `"password`": `"$password`",`n  `"username`": `"$username`",`n  `"timeout`" : 30`n}"

# make it so
$response = Invoke-RestMethod 'http://mullen/webconsole/api/Login' -Method 'POST' -Headers $headers -Body $body

# need to get the token
$token = $response | Select-Object -ExpandProperty token
# the first five characters need to be removed to get just the token
$token = $token.substring(5)

# Now that we have a token we can do things
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Accept", "application/json")
$headers.Add("Authtoken", "$token")
$headers.Add("Content-Type", "application/json")

# Can just read the json file if not interested in replacing variables. Just uncomment the line below and comment out the other $body with JSON
# $body = Get-Content .\Response_payload.json

# Specify JSON here so can input variables.
$body = @"
{
    "storagePolicyName": "$storagePoolName",
    "copyName": "SP_Primary",
    "type": "CVA_REGULAR_SP",
    "numberOfCopies": 1,
    "storagePolicyCopyInfo": {
      "copyType": "SYNCHRONOUS",
      "isDefault": "SET_TRUE",
      "active": "SET_TRUE",
      "storagePolicyFlags": {
        "blockLevelDedup": "SET_TRUE",
        "enableGlobalDeduplication": "SET_TRUE"
      },
      "library": {
        "libraryId": 0
      },
      "mediaAgent": {
        "mediaAgentName": "$mediaAgentName"
      },
      "retentionRules": {
        "retentionFlags": {
          "enableDataAging": "SET_TRUE"
        },
        "retainBackupDataForDays": -1,
        "retainBackupDataForCycles": -1,
        "retainArchiverDataForDays": -1
      },
      "isFromGui": true,
      "numberOfStreamsToCombine": 1,
      "dedupeFlags": {
        "enableDeduplication": "SET_TRUE",
        "enableDASHFull": "SET_TRUE",
        "hostGlobalDedupStore": "SET_TRUE"
      },
      "DDBPartitionInfo": {
        "maInfoList": [
          {
            "mediaAgent": {
              "mediaAgentName": "$mediaAgentName"
            },
            "subStoreList": [
              {
                "accessPath": {
                  "path": "$ddbPath"
                },
                "diskFreeThresholdMB": 5120,
                "diskFreeWarningThreshholdMB": 10240
              }
            ]
          }
        ],
        "sidbStoreInfo": {
          "numSIDBStore": 1
        }
      }
    },
    "clientGroup": {
      "clientGroupId": 0
    },
    "storage": [
      {
        "mediaAgent": {
          "mediaAgentName": "$mediaAgentName"
        },
        "path": "$diskLibPath",
        "credentials": {
          "userName": ""
        }
      }
    ]
  }
"@

# Make it so
$response = Invoke-RestMethod 'http://mullen/webconsole/api/StoragePool?Action=create' -Method 'POST' -Headers $headers -Body $body

# Should specify depth to see all of the JSON as it defaults to only 2 level. Might be more depth if different JSON
$response | ConvertTo-Json -Depth