Scan VMware vSphere vCenter using VIjava, vCenter API


This post is intended for the System/VMware administrator who wants to do get a factual report for the vSphere infrastructure using VMware JAVA API (specifically vijava, open source API optimized by Steve Jin ), here i am sharing a Java program, developed to scan a target vCenter and generate a real time report for the managed entities.

It collects following properties for the entities:

Datastore 

Name: Datastore Name
Capacity: Datastore Capacity in GB
Free: Free Space in Datastore in GB
Free%: Percentage of Free space in Datastore
Cluster: Name of cluster to which Datastore belongs
DC: Name of Datacenter to which Datastore belongs

Host 
 Name: Name of Physical/ESX host
Model: Model of Physical Host
Cores:  No of CPU cores ESX host has
Mem: Total memory Physical Host has in GB
ESX: ESX version of Physical Host. e.g. 5.0,5.5
Build: ESX patch level of Installed ESX
Cluster: Name of cluster to which Datastore belongs
DC: Name of Datacenter to which Datastore belongs

VM 
 Name: Name of Virtual Machine
Cores:  No of CPU cores VM has
Mem: Total memory VM has in GB
State: Power state of VM
Version: VM Hardware version
ToolsStatus: VMware tools status
Cluster: Name of cluster to which Datastore belongs
DC: Name of Datacenter to which Datastore belongs

For an inventory for 83 Host,382 Datastore and 1250 VM, average running time for the program is around 2 min when executed in LAN.

It can be a useful tool for scripting and reporting purpose.

Setup the Development environment:
Using following link you can download required APIs (jars) and setup the environment:
http://vijava.sourceforge.net/doc/getstarted/tutorial.htm
However in the screenshots they have downloaded a older API, we are using the later version available at following link:
http://sourceforge.net/projects/vijava/files/latest/download?source=files
Well i have used Netbeans and this is how my enviroment looks after adding all the required libs:

Vijava Development Environment Snapshot




Source Code:
Its just a single class which takes three command line argument, vCenter name, username and password by which you usually login at vSphere client
  
package vijava55;
import java.net.URL;
import com.vmware.vim25.mo.*;

/**
 *
 * @author Keshav Mukati
 */
public class Main {

    /**
     * @param args the command line arguments VC Name, Username, Password
     */
  public static void main(String[] args) {
    try {
        ServiceInstance si = new ServiceInstance(new URL("https://" + args[0] + "/sdk"), args[1], args[2], true);
        Folder rootFolder = si.getRootFolder();
        ManagedEntity[] mes = new InventoryNavigator(rootFolder).searchManagedEntities("Datacenter");
        if (mes == null || mes.length == 0) {
            return;
        }
        for (ManagedEntity dcmes : mes) {
           Datacenter dc = (Datacenter) dcmes;
           mes = new InventoryNavigator(dc).searchManagedEntities("ClusterComputeResource");
           if (mes == null || mes.length == 0) {
                return;
           }
           for (ManagedEntity clrmes : mes) {
            ClusterComputeResource cluster = (ClusterComputeResource) clrmes;
            Datastore[] dss = cluster.getDatastores();
            if (dss != null) {
              for (Datastore datastore : dss) {
                System.out.print("Object:Datastore~Name:" + datastore.getSummary().getName().replaceAll("\\s", "") + "~");
                System.out.print("Capacity(GB):" + datastore.getSummary().getCapacity() / 1073741824 + "~");
                System.out.print("Free(GB):" + datastore.getSummary().getFreeSpace() / 1073741824 + "~");
                System.out.print("Free(%):" + Math.round((float) datastore.getSummary().getFreeSpace() / datastore.getSummary().getCapacity() * 100) + "~");
                System.out.print("Cluster:" + cluster.getName() + "~");
                System.out.println("DC:" + dc.getName());
               }
             }
             mes = new InventoryNavigator(cluster).searchManagedEntities("HostSystem");
             if (mes == null || mes.length == 0) {
                return;
             }
             for (ManagedEntity hostmes : mes) {
                HostSystem hs = (HostSystem) hostmes;
                System.out.print("Object:Host~Name:" + hs.getName() + "~");
                System.out.print("Model:" + hs.getHardware().getSystemInfo().getModel().replaceAll("\\s", "") + "~");
                System.out.print("Cores:" + hs.getHardware().getCpuInfo().getNumCpuCores() + "~");
                System.out.print("Mem(GB):" + hs.getHardware().getMemorySize() / 1073741824 + "~");
                System.out.print("ESX:" + hs.getConfig().getProduct().getVersion() + "~");
                System.out.print("Build:" + hs.getConfig().getProduct().getBuild() + "~");
                System.out.print("Cluster:" + cluster.getName() + "~");
                System.out.println("DC:" + dc.getName());
                VirtualMachine vmm[] = hs.getVms();

                for (VirtualMachine vm : vmm) {
                    System.out.print("Object:VM~Name:" + vm.getName() + "~");
                    System.out.print("Cores:" + (short) vm.getConfig().getHardware().getNumCPU() + "~");
                    System.out.print("Mem(GB):" + (long) vm.getConfig().getHardware().getMemoryMB() / 1024 + "~");
                    System.out.print("State:" + vm.getRuntime().getPowerState().name() + "~");
                    System.out.print("Version:" + vm.getConfig().getVersion() + "~");
                    System.out.print("ToolStatus:" + vm.getGuest().getToolsStatus().name() + "~");
                    System.out.print("Cluster:" + cluster.getName() + "~");
                    System.out.println("DC:" + dc.getName());
                }
              }
            }
        }
        si.getServerConnection().logout();
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}




How to Run :

Requirement: it can run on any platform, requires only java equal or above 1.6
# java -jar scanVC.jar <VC name> <Username> <password>

Sample output:

[root@abc dist]# java -jar scanVC.jar <VC Name> <Username> <Password>                       //User must have atleast read onlyrights
Object:Datastore~Name:DS-A-01~Capacity(GB):1023~Free(GB):153~Free(%):15~Cluster:clustename~DC:dcname
Object:Datastore~Name:DS-B-02~Capacity(GB):1023~Free(GB):40~Free(%):4~Cluster:clustename~DC:datacentername
….<output truncated>..
Object:Host~Name:abc.corp.amdocs.com~Model:ProLiant BL460c Gen8~Cores:20~Mem(GB):383~ESX:5.0.0~Build:1489271~Cluster:clustename~DC:datacentername
….<output truncated>..
Object:VM~Name:tmp-fed~Cores:2~Mem(GB):8~State:poweredOn~Version:vmx-08~ToolStatus:toolsOk~Cluster:clustename~DC:datacentername
Object:VM~Name:xvt-dev~Cores:2~Mem(GB):4~State:poweredOn~Version:vmx-08~ToolStatus:toolsOk~Cluster:clustename~DC:datacentername
….<output truncated>..

Do clean and build to generate the jar file and execute with the required command line argument, mind to place all the libs at specified location or export CLASSPATH variable.

To distribute this project, zip up the dist folder (including the lib folder) and distribute the ZIP file.

Some Reporting Use case of the Output

We have factual report of all the major entities in the vCenter, now you can simply redirect this output into a file and generate following information using simple shell one liners.

Output redirected to a file for further processing:
 [root@abc dist]# java -jar scanVC.jar VCName Username Password > /tmp/invc


1.View all the details
[root@abc dist]# java -jar scanVC.jar VCName Username Password > /tmp/invc; cat /tmp/invc       //output redirected to a file for further processing

2.View all the cluster and DC in the VC
[root@abc dist]# cat /tmp/invc | grep Host | awk -F "~" '{print $8}' | sort | uniq
[root@abc dist]# cat /tmp/invc | grep Host | awk -F "~" '{print $9}' | sort | uniq

3.Various Virtual machine version
[root@abc dist]# cat /tmp/invc | grep VM | awk -F "~" '{print $6 }'| sort | uniq

4.Datastore attached in a cluster
[root@abc dist]# cat /tmp/invc | grep Datastore | grep CLUSTERNAME | wc -l

5.To see various ESX version in the VC
[root@abc ~]# for i in `cat /tmp/invc | grep Host | awk -F "~" '{print $6}' | sort | uniq`; do echo -e $i; echo -e "Count: `grep $i /tmp/invc | wc -l`"; done

6.To see various ESX build level with the count
[root@abc ~]# for i in `cat /tmp/invc | grep Host | awk -F "~" '{print $7}' | sort | uniq`; do echo -e $i; echo -e "Count: `grep $i /tmp/invc | wc -l`"; done

7.To see various H/W model present
[root@abc scanVC]# for i in `cat /tmp/invc | grep Host | awk -F "~" '{print $3}' | sort | uniq`; do echo -e $i; echo -e "Count: `grep $i /tmp/invc | wc -l`"; done

8.VMware tools status
[root@abc scanVC]# for i in `cat /tmp/invc | grep VM | awk -F "~" '{print $7}' | sort | uniq`; do echo -e $i; echo -e "Count: `grep $i /tmp/invc | wc -l`"; done

9.No of Powered off VM
[root@abc tmp]# cat invc | grep State:poweredOff | wc -l

10.To view all the Datastore where free space is less than 10 percent 
[root@abc scanVC]# for i in `cat /tmp/invc | grep Datastore `; do if [ `echo $i|awk -F "~" '{ print $5 }'|cut -d ":" -f 2` -lt 10 ]; then echo $i; fi; done | more 
And Many more…….


Comments