6 comments

Commvault REST API using PowerShell

Published on Sunday, April 26, 2015 in ,

A while ago I wrote a blog post about Connecting to the 3PAR WebAPI using PowerShell. Today I’m doing the same but now with the Commvault REST API. Connecting to that API is even easier! Commvault has a nice sandbox to get familiar with the REST API! This one is definately worth a look. It can be accessed at http://commvaultwebconsoleserver.contoso.com/webconsole/sandbox/ It looks like this:

2015-02-27_10-29-35_CommvaultRestAPI

Working with the API is similar to the 3PAR approach: first we authenticate and get a token. Then we use that token to call other services. In order to get this working I just looked at the c# sample code Commvault provides: Commvault Documentation: REST API - Getting Started Using C# Here’s how you can authenticate using PowerShell:

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015

#Credentials
$username = "Contoso\s_apiuser" 
$password = P@$$w0rd 
#Commvault web console server
$SERVER = "srdccvws0001.rddcmgmt.local" 
#API URL
$APIURL = "http://$($SERVER):81/SearchSvc/CVWebService.svc" 


$APIURLaction = "$APIURL/login" 
$passwordB64byte = [System.Text.Encoding]::UTF8.GetBytes($password) 
$encodedPassword = [System.Convert]::ToBase64String($passwordB64byte) 
$loginReq = "<DM2ContentIndexing_CheckCredentialReq mode=""Webconsole"" username=""$username"" password=""$encodedPassword"" />" 
$result = Invoke-WebRequest -Uri $APIURLaction -Method POST -Body $loginReq -UseBasicParsing       
$token = (([xml]$result.content).SelectSingleNode("/DM2ContentIndexing_CheckCredentialResp/@token")).value

The code might seem cryptic but is actually pretty straightforward: we need to call the /login service and pass it some parameters.The service requires the password to be base64 encoded. As you might guess this information goes across the wire… So I would definitely advise to use an account that only has permissions to the items it needs to access. Ideally we’d approach the service over SSL but I’m not sure if Commvault allows SSL to be configured for the services.

The username and encoded password have to be passed in a specific XML string that is passed as the body of the web request. The result is an XML string that contains a token value. We don’t need the whole string but only the part representing the token. Now that we managed to get a token we can start calling specific services. If I'm not mistaken this token will remain valid until there’s a period of inactivity (30’).

Here’s how you can get all Clients:

001
002
003
004
005
006
007
008
009
010

$service = "/client" 
$action = "GET" 
$APIURLaction = "$APIURL$service" 
$headers = @{} 
#default is XML
$headers["Accept"] = "application/json" 
$headers["Authtoken"] = $token 
$result = Invoke-WebRequest -Uri $APIURLaction -Headers $headers -Method $action -UseBasicParsing 
$clientInfo = ($result.content | ConvertFrom-Json).App_GetClientPropertiesResponse.clientProperties
 

If you go through the REST API documentation you’ll notice that some services are GET based and other are POST based. The /client service is GET based, the /jobdetails is POST based. You’ll also notice that we pass an XML string as the body for the request.

001
002
003
004
005
006

$jobID = "3040" 
$body = "<JobManager_JobDetailRequest jobId=""$jobID""/>" 
$service =  "/JobDetails" 
$action = "POST" 
$result = Invoke-WebRequest -Uri $APIURLaction -Headers $headers -Method $action -UseBasicParsing -Body $body 
$jobDetails = ($result.content | ConvertFrom-Json).JobManager_JobDetailResponse.job.jobDetail

I hope with these basic examples you can now successfully connect yourself. As you might see, the above code contains no error handling. Depending on how you will use scripts like that I would advise to add some logging and error handling. Try providing wrong credentials or entering a bad servername and see what happens.