Recently I posted about the new PowerCLI 5.5R2 capability to interact with the SRM API, and I want to write a few posts on using those capabilities to automate some typical (and perhaps some atypical) activities one might wish to accomplish. In the next few posts I’ll be showing some of the things you can do like:
- How the SRM API is structured and how to access it through PowerCLI
- Walk through the examples given in the documentation
- How to generate reports
- How to add VMs to existing protection groups
- How to automate test failovers
I am not a PowerCLI genius, so there is a good chance these scripts will not be the most elegant approach you could take, but hopefully this will give you an idea of what’s possible to do with this interaction.
First, let’s take a look at how we actually go about accessing the SRM API through PowerCLI.
The first thing to note is that there are only two (2) cmdlets for the SRM API, one to connect and one to dis-connect. There are currently no other SRM related cmdlets to help you automate SRM tasks. PowerShell and PowerCLI are normally designed around creating high level abstractions in the form of commands (or as they are called in PowerShell “cmdlets”) to execute what would normally be low level calls to an API. A cmdlet is designed to be a simple call to what might normally be a number of layers of API calls to make it easier for end users to achieve their tasks. Since there are no cmdlets for SRM operations yet, just the connect and dis-connect, the situation in which we find ourselves today is that we need to use PowerCLI to interact directly with the API without the benefit of the high level cmdlets.
This was a design decision made by the PowerCLI team and offers us the full functionality of the SRM Public API: It allows us to get started in a slightly more difficult way than the high level cmdlets and also allows the PowerCLI team see the kind of things that SRM administrators want to automate.
What that means for us is that in order to automate and script things we need to have a fairly good understanding of the SRM API.
The SRM API is built hierarchically with a top-down approach that branches as we delve further into it. At the top level we have the full API which is obviously a function of the SRM server. In order to access it from PowerCLI we need to first connect to the SRM server itself. This is done with one of the few SRM cmdlets that are available, “Connect-SrmServer”.
1 2 |
Connect-ViServer –server 10.20.181.30 Connect-SrmServer |
The first command attaches PowerCLI to the appropriate vCenter, in this case, the vCenter that manages my primary site in my lab at the IP specified. You can pass it particular credentials, but in my case I’m using my current account which happens to be a domain admin in my lab.
Likewise, the second command then connects to the SRM server that has been registered with the vCenter to which I’m already connected. Likewise I could specify a different SRM server or different credentials, but in my case I can use my current account and the SRM server that is registered with the vCenter as a service.
This has now created a variable called $DefaultSrmServers to which all SRM specific API commands will be sent. I could attach to further servers at which point I would have $DefaultSrmServers[0], [1], etc. If I wanted to send my commands to those servers I would specify that at the time of running a method.
The act of connecting to that server has a few results. Most importantly it will query that connection and generate what is referred to as a “View” of the service associated with that connection. The View is an interrogation of the API present and gives us all the methods (actions that can be taken) and properties (current values associated with objects in the API), and thereby we have a framework in which PowerCLI can work with SRM.
Since variables are great things to work with as they aid in the discovery, and allow fewer calls to the SRM API (because they are stored locally) let’s assign a variable to the connection:
$SrmConnection=Connect-SrmServer 10.20.181.32
We can now query that connection and see all the properties and methods within our default variable:
$SrmConnection | Get-Member
Piping the connection to the “Get-Member” cmdlet (“gm” short form) will then query the connection for their appropriate methods and properties.
The connection has a very important object, called the ExtensionData. ExtensionData is really the entry point into the API. All our commands will need to be run against the ExtensionData, and so one very easy way to work with this is to assign the connection.extension to a variable we can use hereafter, as per the following example:
1 |
$SrmApi = $SrmConnection.ExtensionData |
This will make it much simpler for all subsequent commands once we are connected, as we can now simply type “$SrmApi” for all our commands rather than “$SrmConnection.ExtensionData” every time we want to do an action.
For example, we can now run $SrmApi within PowerCLI as a form of query to interrogate the connection and see what top level properties are available in the API.
1 |
$SrmApi |
You can see there are objects returned for primitive objects like Content, Recovery and Protection, which are key controls within SRM. Piping this again to the “Get-Member” cmdlet will then query these objects for their appropriate methods and properties.
Let’s pause now and take a look at the SRM API structure.
Page 9 of the SRM API Developer’s Guide (https://www.vmware.com/support/developer/srm-api/srm_50_api.pdf at time of writing) contains a very clear image documenting the structure of the methods available within the API.
You can see there is the top level instance, which contains a content library with a few key structures: SrmProtection and SrmRecovery. There are more than these two objects in the API, but from an interactive perspective these are the two main areas in which we are likely to want to work.
You will need to understand the structure of the API in order to query properties or execute methods, as you need to inform both PowerCLI and the API very precisely what it is you want to do. This is because the cmdlets are not there to interpret your commands. Rather than simply running something that says “ListProtectedVMs” as you may be able to do with a cmdlet, you’ll need to issue the full path to the API method in the appropriate context, while giving the appropriate input in terms of protection group instance and so forth.
So keep in mind commands usually will fall into property queries or methods for execution, and usually fall within either the protection or recovery stacks of the API.
Once you understand the hierarchy of the API, I suggest you go examine the rest of pages 8 and 9 of the guide to understand the scope of methods available to you.
Once that’s done, we can start executing commands against the API!
Here’s an example:
1 |
$SrmApi.Protection.ListProtectionGroups() |
The empty brackets at the end are to say that I am not passing it any values, just querying. You can see that on this server I have two protection groups defined, and it is passing back to me their managed object reference. The managed object reference (“MoRef”) is a unique ID used by the API to identify a particular entity.
We can assign that to a variable:
1 |
$ProtectionGroups=$SrmApi.Protection.ListProtectionGroups() |
Now we can query the variable for further data:
1 |
$ProtectionGroups|GM |
Hmm… ListProtectedVMs looks like it could be useful.
Let’s query the first protection group for what VMs it contains.
1 |
$ProtectionGroups[0].ListProtectedVMs() |
And here we see a list of what protected VMs are in the protection group and what their state is.
Let’s take a look at another example.
1 |
$SrmApi.Recovery.Listplans() |
Nice – three recovery plan MoRefs.
Let’s say I just want to work with one of those plans or groups. We can append the command with the numeric value [0] or 1 or 2…
1 |
$SrmApi.Recovery.Listplans()[0] |
If I want to know what I can do with that plan list method, I can do the get-member to list what is contained:
1 |
$SrmApi.Recovery.Listplans()[2] | gm |
I can see that I can GetInfo, so let’s see the result of that:
1 |
$SrmApi.Recovery.Listplans()[2].GetInfo() |
Again the empty brackets as I’m not passing any information in.
We can now see the Name, Description, State, and ProtectionGroups for this recovery plan!
So this is how you start off with the API. We’ve seen how to connect to it, how that generates a view, and how to query some of the protection and recovery objects in the API.
In the next few posts I do, we’ll start with some scripting!