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:
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.
6 Response to Commvault REST API using PowerShell
Thanks thomas for the great info, was struggling with how to store and use the token for other API calls, new to REST but seeing your code examples was like a light bulb going off.
Thanks for the thumbs up!
This was really helpful to get me started. Thanks! However I'm not happy to implement anything like this as I'm concerned about authenticating and sending a simple encoded password without encryption. Have you looked doing this over https?
Sorry I've never worked with this again after I posted this. Ideally the API should be exposable over HTTPS...
Thank you very much Thomas. Now I will monitor Commvault infos with Zabbix using this script.
Add Your Comment