Category Archives: DRS, SDRS

drs dpm sdrs sioc related posts/scripts

Some of useful VMware PowerCLI scripts added into VMware Sample Exchange

Recently while working on couple of customer cases, I had to write some useful vSphere PowerCLI scripts. I had submitted these scripts on VMware Sample Exchange, I thought to share on blog as well. If you haven’t still explored VMware Sample Exchange , please have your “My VMware” account created (Mandatory to have My VMware account to contribute or request) and enjoy the single pane of glass for VMware API samples across any product, any programming language and any platform (including CLIs). You can browse already existing samples as well as request new API sample that you are looking for. This is really cool site for learning VMware APIs, it is a must book-mark if you ask me. Here is the VMTN Sample Exchange community for more details.

Here we go for the PowerCLI scripts that I am talking about.

Below are the use-cases these script will help you on.

1. Report on vSphere compute cluster usage/capacity data on CPU, Memory and Storage.
2. Report on DRS VM-VM affinity rules associated with each VMs in the cluster.
3. Solution 1 : Report on VMs with “multi-writer” flag enabled.
4. Solution 2: Report on VMs with “multi-writer” flag enabled.

1. Report on vSphere compute cluster usage/capacity data on CPU, Memory and Storage. Sample exchange script location

< # .SYNOPSIS Getting Cluster usage/capacity data on CPU, Memory and Storage .NOTES Author: Vikas Shitole .NOTES Site: www.vThinkBeyondVM.com .NOTES Reference: http://vthinkbeyondvm.com/category/powercli/ .NOTES Please add the vCenter server IP/credentails as per your environment #>

Connect-VIServer -Server 10.92.166.82 -User Administrator@vsphere.local -Password xyz!23

$report = @()

Write-host "Report Generation is in Progress..."

foreach ($cluster in Get-Cluster ){

$row = '' | select ClusterName,CpuCapacity , CpuUsed, MemCapacity,MemUsed ,StorageCapacity,StorageUsed

$cluster = Get-Cluster -Name $clusterName
$cluster_view = Get-View ($cluster)
$resourceSummary=$cluster_view.GetResourceUsage()
$row.ClusterName =$cluster_view.Name
$row.CpuCapacity =$resourceSummary.CpuCapacityMHz
$row.CpuUsed =$resourceSummary.CpuUsedMHz
$row.MemCapacity =$resourceSummary.MemCapacityMB
$row.MemUsed =$resourceSummary.MemUsedMB
$row.StorageCapacity =$resourceSummary.StorageCapacityMB
$row.StorageUsed =$resourceSummary.StorageUsedMB

$report += $row
}
$report | Sort ClusterName | Export-Csv -Path "D:Clusterstats.csv" #Please change the CSV file location

Write-host "Report Generation is completed, please chekc the CSV file"

2. Report on DRS VM-VM affinity rules associated with each VMs in the cluster. Sample Exchange script location

< # .SYNOPSIS Getting DRS VM-VM affinity rules associated with each VMs in the cluster. .NOTES Author: Vikas Shitole .NOTES Site: www.vThinkBeyondVM.com .NOTES Reference: http://vthinkbeyondvm.com/category/powercli/ .NOTES Please add the vCenter server IP/credetails as per your environment #>

Connect-VIServer -Server 10.192.x.y -User Administrator@vsphere.local -Password xyz!23

$clusterName = "BLR" #Your cluster name
$cluster = Get-Cluster -Name $clusterName
$vms = Get-View ($cluster| Get-VM)
$cluster_view = Get-View ($cluster)

$report = @()

Write-host "Report Generation is in Progress..."

foreach ($vm in $vms ){

$row = '' | select VMName, Rules
$rules=$cluster_view.FindRulesForVm($vm.MoRef)
$ruleNameArray=" "
#There can be more than one rule assciated with single VM
foreach($rule in $rules){
$ruleNameArray+=$rule.Name
$ruleNameArray+=","
}
$row.VMName =$vm.Name
$row.Rules = $ruleNameArray
$report += $row
}
$report | Sort Name | Export-Csv -Path "D:VMsRules.csv" #Please change the CSV file location

Write-host "Report Generation is completed, please chekc the CSV file"

3. Solution 1 : Report on VMs with “multi-writer” flag enabled. Sample exchange script location

< # .SYNOPSIS: This script first downloads all the VMX files (per host/cluster/datacenter/VC)at specified file location .Once downloaded, it will scan each VMX file one by one to get "multi-writer" entry inside VMX .Finally it will list all matching VMX file names into specified file location. .As it downloads all the VMX files, it is going to take more time, that should be fine. .It is all right to download the VMX file when VM is up and running. .If name of the VM is changed, VMX file can be different from VM display name (visible from inventory). .There are 2 file locations you need to specify. 1. Directory where VMX file will be downloaded 2. Output file. .NOTES Author: Vikas Shitole .NOTES Site: www.vThinkBeyondVM.com .NOTES Reference: http://vthinkbeyondvm.com/category/powercli/ and https://communities.vmware.com/message/2269363#2269363 .NOTES Please add the vCenter server IP/credetails as per your environment .NOTES Alternatively you can use this script where API properties are used. https://github.com/vThinkBeyondVM/vThinkBVM-scripts/blob/master/Powershell-PowerCLI/VMMultiWriterReport.ps1 #>

Write-host "Connecting to vCenter server.."
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -DisplayDeprecationWarnings:$false -Scope User
Connect-VIServer -Server 10.192.67.143 -User administrator@vsphere.local -Password Admin!23

$tgtFolder = "C:\Temp\VMX\" #Create this directory as per your environment
#$tgtString = 'scsi0:0.sharing="multi-writer"'
$tgtString = '"multi-writer"'
foreach ($vm in Get-VM ){

Get-VM -Name $vm.get_Name() | %{
$dsName,$vmxPath = $_.ExtensionData.Config.Files.VmPathName.Split()
$dsName = $dsName.Trim('[]')
$ds = Get-Datastore -Name $dsName
New-PSDrive -Location $ds -Name DS -PSProvider VimDatastore -Root "\" | Out-Null
Copy-DatastoreItem -Item "DS:$vmxPath" -Destination $tgtFolder
Remove-PSDrive -Name DS -Confirm:$false
}

}
Get-ChildItem -Path $tgtFolder -Filter "*.vmx" | Where {Get-Content -Path $_.FullName | Select-String -Pattern $tgtString} | Select Name | Out-File C:\test1.txt
Write-host "Execution is done... please check the file with all VMX file names."

# Below cmdlet can help to scan VMs per Datacenter/Datastore/Host/Cluster. Please modify the script as required.

#$myDatacenter = Get-Datacenter -Name "MyDatacenter"
#Get-VM -Location $myDatacenter

#$myDatastore = Get-Datastore -Name "MyDatastore"
#Get-VM -Datastore $myDatastore

#$myHost=Get-VMHost -Name "HostName"
#Get-VM -Location $myHost

#$myCluster=Get-Cluster -Name "ClusterName"
#Get-VM -Location $myCluster

4. Solution 2 : Report on VMs with “multi-writer” flag enabled. Sample Exchange script location

< # .SYNOPSIS: This script connects to the vCenter Server and prepares a report on All VMs with at-least one disk enabled with "Multi-Writer" sharing. .Report will be generated as CSV file with "VM Name". This can be modified to add some more columns as needed .VC IP/UserName/Password are hardcoded below, please change them as per your environment .By default this script scans all the VMs/VMDK in the vCenter Server. It can be easily twicked to scan VM per cluster or host or datacenter .NOTES Author: Vikas Shitole .NOTES Site: www.vThinkBeyondVM.com .NOTES Reference: http://vthinkbeyondvm.com/category/powercli/ .NOTES Please add the vCenter server IP/credetails as per your environment Alternate solution by scanning VMX file is here: https://github.com/vThinkBeyondVM/vThinkBVM-scripts/blob/master/Powershell-PowerCLI/VMMultiWriterReport2.ps1 #>

Write-host "Connecting to vCenter server.."
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -DisplayDeprecationWarnings:$false -Scope User
Connect-VIServer -Server 10.192.x.y -User administrator@vsphere.local -Password xyz@123

$report = @()
Write-host "Report Generation is in Progress..."

foreach ($vm in Get-VM ){
$view = Get-View $vm
$settings=Get-AdvancedSetting -Entity $vm
if ($view.config.hardware.Device.Backing.sharing -eq "sharingMultiWriter" -or $settings.value -eq "multi-writer"){
$row = '' | select Name
$row.Name = $vm.Name
$report += $row
}

}
$report | Sort Name | Export-Csv -Path "D:MultiWriter.csv" #Please change the CSV file location

Write-host "Report is generated successfully, please check the CSV file at specified location"

#If you want to generate report per Datacenter/Datastore/Host/Cluster, modify script using below code.

#$myDatacenter = Get-Datacenter -Name "MyDatacenter"
#Get-VM -Location $myDatacenter

#$myDatastore = Get-Datastore -Name "MyDatastore"
#Get-VM -Datastore $myDatastore

#$myHost=Get-VMHost -Name "HostName"
#Get-VM -Location $myHost

#$myCluster=Get-Cluster -Name "ClusterName"
#Get-VM -Location $myCluster

Great vSphere API ever: Part -I : placevm() API which places the VM on best possible host and datastore

This is the vSphere API personally I was waiting for since long days, I believe this is one of the powerful vSphere APIs ever. The API I am talking about is introduced as part of vSphere 6.0 i.e. placevm(). Here is the API reference for the same.

Why this API is so powerful?
-Basically this API helps to place the VM on appropriate host and datastore. Placing the VM can be as part of creating the VM, relocating the VM, cloning the VM or re-configuring the existing VM.
-How does this API achieves the best host from CPU and Memory perspective and datastore from storage perspective? As per API reference, this API can be invoked to ask DRS (Distributed resource scheduler) for a set of recommendations for placing a virtual machine and its virtual disks into a DRS cluster.
-This API offers so much flexibility that, from storage perspective, it can take input as set of datastores of our choice as well as set of SDRS (Storage DRS) PODs, we can even specify one particular datastore of our choice. From compute perspective, it takes set of hosts or particular host as input. How cool is that when DRS is involved and SDRS POD(s)?
-It also gives us flexibility on not to specify any hosts as well as datastores, in that case, it automatically picks all the hosts inside the DRS cluster and all the datastores connected to hosts inside the cluster.
– Another beauty of this API is, it works perfectly with SPBM (Storage Policy Based Management) as well as across vCenter server. is not it something great capability into single API?

Lets learn now how to use this API in real time. For the sake simplicity I have divided this post into 2 parts.

Part I: How to relocate a Powered ON VM from a DRS enabled cluster to another DRS enabled cluster (One SDRS POD as input) within single vCenter
Part II: How to relocate a Powered ON VM from a DRS enabled cluster to another DRS enabled cluster (Multiple SDRS PODs as input) across vCenter.

Below is the placeVM API sample that achieves the Part I where we invoke placeVM API to get the set of recommendations for VM (cpu, mem, storage) and then we invoke RelocateVM API to apply one of the first recommendations.

Same sample is available on my git hub repository as well as on VMware Sample exchange

//:: # Author: Vikas Shitole
//:: # Website: www.vThinkBeyondVM.com
//:: # Product/Feature: vCenter Server/DRS
//:: # Reference:
//:: # Description: Tutorial: PlaceVM API: Live relocate a VM from one DRS cluster to another DRS cluster (in a Datacenter or across Datacenter)
//:: # How cool is it when DRS takes care of placement from cpu/mem perspective and at the same time SDRS take care of storage placement
//::# How to run this sample: http://vthinkbeyondvm.com/getting-started-with-yavi-java-opensource-java-sdk-for-vmware-vsphere-step-by-step-guide-for-beginners/

package com.vmware.yavijava;

import java.net.MalformedURLException;
import java.net.URL;
import com.vmware.vim25.ClusterAction;
import com.vmware.vim25.ClusterRecommendation;
import com.vmware.vim25.ManagedObjectReference;
import com.vmware.vim25.PlacementAction;
import com.vmware.vim25.PlacementResult;
import com.vmware.vim25.PlacementSpec;
import com.vmware.vim25.VirtualMachineMovePriority;
import com.vmware.vim25.VirtualMachineRelocateSpec;
import com.vmware.vim25.mo.ClusterComputeResource;
import com.vmware.vim25.StoragePlacementSpecPlacementType;
import com.vmware.vim25.mo.Datacenter;
import com.vmware.vim25.mo.Datastore;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ManagedEntity;
import com.vmware.vim25.mo.ResourcePool;
import com.vmware.vim25.mo.ServiceInstance;
import com.vmware.vim25.mo.StoragePod;
import com.vmware.vim25.mo.VirtualMachine;

public class PlaceVMRelocate {

public static void main(String[] args) throws Exception {
if(args.length!=3)
{
System.out.println("Usage: PlaceVMRelocate url username password");
System.exit(-1);
}

URL url = null;
try
{
url = new URL(args[0]);
} catch ( MalformedURLException urlE)
{
System.out.println("The URL provided is NOT valid. Please check it...");
System.exit(-1);
}
String username = args[1];
String password = args[2];
String SourceClusterName = "Cluster1"; //Source cluster Name, It is not required to have DRS enabled
String DestinationClusterName="Cluster2"; //Destination cluster with DRS enabled
String SDRSClusterName1="POD_1"; //SDRS POD
String VMTobeRelocated="VM2"; //VM Name to be relocated to other cluster
ManagedEntity[] hosts=null;

// Initialize the system, set up web services
ServiceInstance si = new ServiceInstance(url, username,
password, true);
if(si==null){
System.out.println("ServiceInstance Returned NULL, please check your vCenter is up and running ");
}
Folder rootFolder = si.getRootFolder();
ManagedObjectReference folder=rootFolder.getMOR();
StoragePod pod1=null;

//Getting datacenter object
Datacenter dc=(Datacenter) new InventoryNavigator(rootFolder)
.searchManagedEntity("Datacenter", "vcqaDC");

//Getting SDRS POD object
pod1=(StoragePod) new InventoryNavigator(rootFolder)
.searchManagedEntity("StoragePod", SDRSClusterName1);
ManagedObjectReference podMor1=pod1.getMOR();
ManagedObjectReference[] pods={podMor1};

//Getting source cluster object, It is NOT needed to enable DRS on source cluster
ClusterComputeResource cluster1 = null;
cluster1 = (ClusterComputeResource) new InventoryNavigator(rootFolder)
.searchManagedEntity("ClusterComputeResource", SourceClusterName);

//Getting VM object to be relocated
VirtualMachine vm=null;
vm=(VirtualMachine) new InventoryNavigator(cluster1)
.searchManagedEntity("VirtualMachine", VMTobeRelocated);
ManagedObjectReference vmMor=vm.getMOR();

//Getting destination cluster object, DRS must be enabled on the destination cluster
ClusterComputeResource cluster2 = null;
cluster2 = (ClusterComputeResource) new InventoryNavigator(rootFolder)
.searchManagedEntity("ClusterComputeResource", DestinationClusterName);
ManagedObjectReference cluster2Mor=cluster2.getMOR();

//Getting all the host objects from destination cluster.
hosts = new InventoryNavigator(cluster2).searchManagedEntities("HostSystem");
System.out.println("Number of hosts in the destination cluster::" + hosts.length);
ManagedObjectReference[] hostMors=new ManagedObjectReference[hosts.length];
int i=0;
for(ManagedEntity hostMor: hosts){
hostMors[i]=hostMor.getMOR();
i++;
}

//Building placement Spec to be sent to PlaceVM API
PlacementSpec placeSpec=new PlacementSpec();
placeSpec.setPlacementType(StoragePlacementSpecPlacementType.relocate.name());
placeSpec.setPriority(VirtualMachineMovePriority.highPriority);
// placeSpec.setDatastores(dss); //We can pass array of datastores of choice as well
placeSpec.setStoragePods(pods); // Destination storage SDRS POD (s)
placeSpec.setVm(vmMor); //VM to be relocated
placeSpec.setHosts(hostMors); //Destination DRS cluster hosts/ We can keep this unset as well
placeSpec.setKey("xvMotion placement");
VirtualMachineRelocateSpec vmrelocateSpec=new VirtualMachineRelocateSpec();
vmrelocateSpec.setPool(cluster2.getResourcePool().getMOR()); //Destination cluster root resource pool
vmrelocateSpec.setFolder(dc.getVmFolder().getMOR()); //Destination Datacenter Folder
placeSpec.setRelocateSpec(vmrelocateSpec);
PlacementResult placeRes= cluster2.placeVm(placeSpec);
System.out.println("PlaceVM() API is called");

//Getting all the recommendations generated by placeVM API
ClusterRecommendation[] clusterRec=placeRes.getRecommendations();
ClusterAction[] action= clusterRec[0].action;
VirtualMachineRelocateSpec vmrelocateSpecNew=null;
vmrelocateSpecNew=((PlacementAction) action[0]).getRelocateSpec();
vm.relocateVM_Task(vmrelocateSpecNew, VirtualMachineMovePriority.highPriority);

si.getServerConnection().logout();
}

}

Notes:
– For the sake of simplicity I have hardcoded some variables, you can change as per your environment
– We can leverage this sample either within a single vCenter datacenter or across vCenter datacenters.
– All the required documentation is added inside the sample itself. Source cluster need not to be DRS enabled.
-Same Sample can used not only for relocate ops but also clone, create and reconfigure VM Ops.

If you have still not setup your YAVI JAVA Eclipse environment:Getting started tutorial

Important tutorials to start with: Part I & Part II