SRM, PowerCLI, and custom functions

One of the important benefits of the new PowerCLI release is that it exposes SRM’s public API in a relatively easy to consume manner. Having said that calling SRM API methods directly via PowerCLI is not exactly idiomatic. Here’s the example from the PowerCLI user guide on how to protect a VM.

# Connect to the vCenter Server system that the SRM server is registered with.
 Connect-VIServer -Server vc3.example.com -User 'MyAdministratorUser' -Password 'MyPassword'

 # Establish a connection to the local SRM server by providing credentials to the remote SRM site.
 $srm = Connect-SrmServer -RemoteUser 'MyRemoteUser' -RemotePassword 'MyRemotePassword'

 # List all protection groups associated with the SRM server.
 $srmApi = $srm.ExtensionData
 $protectionGroups = $srmApi.Protection.ListProtectionGroups()

 # Associate the TestVM virtual machine with the ProtGroup1 protection group and enable the protection for that virtual machine.
 $vmToAdd = Get-VM "TestVM"
 $targetProtectionGroup = $protectionGroups | where {$_.GetInfo().Name -eq "ProtGroup1" }
 $targetProtectionGroup.AssociateVms(@($vmToAdd.ExtensionData.MoRef)) # VR specific call

 # Enable protection for that virtual machine
 $protectionSpec = New-Object VMware.VimAutomation.Srm.Views.SrmProtectionGroupVmProtectionSpec
 $protectionSpec.Vm = $vmToAdd.ExtensionData.MoRef
 $protectTask = $targetProtectionGroup.ProtectVms($protectionSpec)
 while(-not $protectTask.IsComplete()) { sleep -Seconds 1 }

While the code is reasonably straightforward to follow along it doesn’t follow the PowerShell style and we can certainly try and simplify it.

What I am going to show is how you can create custom functions that make it easier to hide this complexity when you are trying to get stuff done. For example how about we replace all that API wrangling with a couple of custom functions? Something like this perhaps:

# Connect to the vCenter Server system that the SRM server is registered with.
 Connect-VIServer -Server vc3.example.com -User 'MyAdministratorUser' -Password 'MyPassword'

 # Establish a connection to the local SRM server by providing credentials to the remote SRM site.
 Connect-SrmServer -RemoteUser 'MyRemoteUser' -RemotePassword 'MyRemotePassword'

 # Find the protection group
 $pg = Get-ProtectionGroup -Name 'ProtGroup1'

 # Protect the Virtual Machine
 Get-VM -Name 'TestVM' | Protect-VM -ProtectionGroup $pg

In this example we’ve reduced 11 lines of API heavy code into 4 fairly simple lines by creating a couple of custom functions Get-ProtectionGroup and Protect-VM. These custom functions enable us to hide the complexity of calling the API directly. Here’s a quick video demonstrating this in action.

But we don’t have to stop there! SRM’s API exposes a lot of operations so there is plenty to automate. Let’s say you wanted a list of Virtual Machines that are included in a recovery plan, with custom functions this could be as easy as chaining together cmdlets to retrieve the recovery plan, find any associated protection groups and then the retrieve the VMs associated with those groups, e.g.:

Get-RecoveryPlan -Name 'Failover Site A' | Get-ProtectionGroup | Get-ProtectedVm

…much simpler than having to call into the SRM API directly!

I’ve got very limited experience with PowerCLI but it wasn’t too difficult for me to knock up a few PowerCLI functions to do this. I’ve shared my SRM custom functions on Github (for illustrative purposes) and it has certainly proven useful for me. Hopefully there are some PowerCLI gurus out there and the community who can fix all the obvious mistakes I’ve no doubt made and share something better with the community!

Please share your feedback and let me know what kind of SRM operations you’d like to be able to automate and why.