Skip to main content

Unmounting VMFS Datastores using vRO

Being a diligent admin, I always unmount a datastore from an ESXi server prior to completely deleting it.  It's a good way to verify the datastore isn't being used before the storage admin removes the ESXi server's visibility to the lun.  This is a task that I really want to perform in vRealize Orchestrator (vRO) instead of having to unmount the datastore from the ESXi server manually.  SPOILER ALERT - I'll include a workflow that allows you to execute the unmount across multiple ESXi servers in parallel at the end of this post.

The first step is to see what's available from an unmount standpoint.  We start by bringing up the API Explorer under the Tools menu.


From here we can search the "Attributes & methods" for text that contains the word unmount.  There quite a few methods which contain the text unmount.  I'm going to focus on the VcHostStorageSystem.unmountVmfsVolume() method.  


This method takes a single argument - the uuid of the VMFS datastore that we are unmounting.  So, the next step is to search for attributes that contain the text uuid.  For this, we'll use the VcHostVmfsVolume.uuid attribute.  We can get to this attribute using the by traversing the datastores "info" (VcDatastoreInfo) attribute and then the vmfs (VcHostVmfsVolume) attribute.


Now that we can get the uuid value for the datastore we can start doing some actual programming.  I want to provide reusable method (i.e. Action) that anyone can use in a workflow.  To do that we change from "Run" to "Design" view and then select the "Action" icon in the designer UI.  Right-click on the folder where you want to place the action (or create a new folder) and select "Add action..." 


From here, click on the yellow arrow to add parameters.  The first parameter is the vmhost and the second is the datastore.  Make sure to set the parameter types correctly - the default type is string which is not correct for our parameters. Then we add a small piece of code to unmount the datastore from the vmhost.
  

Now that we have coded the action, we go back to the Workflow designer to create a "New workflow"


Just like before, we add two parameters (vmhost and datastore) and just like before we have to set the parameter types correctly.


BONUS!!  One of the features I really like with vRO (and vCO) is the presentation.  This allows you to the customize input form when the workflow is executed.  We'll start by adding a description under the General tab for both the vmhost and the datastore.  This text will be displayed when the workflow is executed.  Next we add properties to both the vmhost and the datastore.  For the vmhost, we'll add only the "mandatory input" property so that the workflow cannot be started if this parameter is omitted.


For the datastore, we add the mandatory input but also add the "specify a root object to be shown in the chooser".  This filters what is displayed based on the vmhost that is selected as the first parameter.   


Now we go to the Schema tab and drag the "Action element" into the workflow.  In the search filter we look for unmount and find the action we created in the step above.


This *should* synchronize the parameters for us.


I also drag the "Throw exception" element over the top of my unmountDatastoreFromVmhost so that the workflow will throw an exception if an error occurs during the unmount.  If you want to include additional text for the error then you can edit the exception and add your text to the "Business status" box.


We're now ready to execute the workflow.  This can be done by clicking on "Run" at the top of the Schema window.  In the pop-up window click on vmhost parameter "Not set" to select the ESXi Server to unmount a datastore.


Now, click on datastore parameter "Not set" to select a datastore. You'll notice that the root object in the ESXi server you selected in the step above - just like we planned thanks to the workflow presentation.  Finally, click the Submit button to execute the workflow.


By creating this simple workflow to unmount a datastore from a ESXi server we could then do a few of things:
  1. provide storage admins access to the workflow through either the vRO GUI or through the vSphere Web client to execute the workflow
  2. create a workflow that loops through multiple ESXi servers to unmount a datastore
  3. create a workflow that loops through multiple datastores and unmounts those from a single ESXi server
  4. create a workflow that loops through multiple datastores and unmounts those from multiple ESXi servers
Item #2 is the one that interests me.  If a datastore needs to be unmounted from every ESXi server in a cluster then calling this simple workflow for every ESXi server in that cluster will do the trick.  And, if I call this workflow as an "Asynchronous workflow", then ALL ESXi servers will unmount the datastore in parallel!  That's exactly what I've done in this workflow package.  Simply download the package and import it into your vRO server using the designer UI.  That's it!

Are you doing storage refresh and migrating VMs from one storage array to another?  That would be the use case for item #4.  You can leverage this simple workflow to automate the unmount of the datastores from multiple ESXi severs.  Have Fun Orchestrating!      

Comments

Post a Comment

Popular posts from this blog

Querying for nested folders with PowerCLI

Have you fought trying to query nested, duplicate-named folders?  Hopefully this will help solve the problem!  Suppose you have a VM folder-tree similar to this:


So, how do you get the "\dotcom\linux\dev" folder using PowerCLI?  If you query for just "dev" then you can get an array of folders.
You can parse through the array and, using the parent object, traverse the tree backwards validating the folder names.  But, what if you have 100s of folders?  In my opinion, this is not an optimal approach.  We really need to do this:

This is great case for recursion.  In my words, recursion is a "stack" of operations.  When an operation completes its result is used by the next operation in the "stack".  Most importantly there has to be base-case which causes the last operation in the stack to return a valid result.  Then each operation can be popped off the "stack" and its result can be used by the previous operation until the final result is obta…

Reconnecting ESXi servers with PowerCLI

We recently needed to re-ip our vCenter servers; each with ~200 ESXi servers which needed to be reconnected - thank goodness for PowerCLI.  Since there isn't a "Reconnect-VMHost" cmdlet provided by PowerCLI we needed to check the HostSystem Object at https://www.vmware.com/support/developer/converter-sdk/conv55_apireference/vim.HostSystem.html and to see what methods were available (hint: there's a ReconnectHost_Task method which will do the trick).  We can still leverage the "Get-VMHost" cmdlet to return the disconnected ESXi servers and then call the ReconnectHost_Task method to reconnect each ESXi server.  The code is fairly short:

Get-VMHost -state Disconnected | foreach-object {
  $vmhost = $_
  $connectSpec = New-Object VMware.Vim.HostConnectSpec
  $connectSpec.force = $true
  $connectSpec.hostName = $vmhost.name
  $connectSpec.userName = 'root'
  $connectSpec.password = 'MySecretPassword'
$vmhost.extensionData.ReconnectHost_Task($connectSpec,…

Parsing XML with VMware Orchestrator

For my first blog I thought I would start with something easy - parsing XML using VMware Orchestrator (a.k.a vCO)!  I started playing with vCO in September 2012 for a "Cloud" project so I still consider myself a newbie - if you happen across this post and find something incorrect or something that could be done better then please don't hesitate to speak up.

Since I can't post our actual XML, I'll be using the following XML which will give the gist of how to parse for elements & attributes.

<?xml version="1.0" encoding="UTF-8" ?>
<people>
  <person firstname="Jack" lastname="Smith" age="40">
    <phone type="home" number="1234567890" />
    <phone type="cell" number="1234567891" />
<sport name="basketball" position="shooting guard" />
  </person>
  <person firstname="Jill" lastname="Smith" age=&q…