This post was driven by a requirement to map RDM volumes on target side in preparation for a disaster recovery test. I thought I would share some of my automation and process with regards to mapping RDM devices that will be used to present RecoverPoint replicated devices to VMs as part of a DR test.
Step 1: Install VMware vCLI and PowerCLI
Step 2: Open PowerCLI command prompt
Step 3: Execute addvcli.ps1 (. .\addvcli.ps1)
function Add-vCLIfunction { <# .SYNOPSIS Adds the VMware vSphere Command-Line Interface perl scripts as PowerCLI functions. .DESCRIPTION Adds all the VMware vSphere Command-Line Interface perl scripts as PowerCLI functions. VMware vSphere Command-Line Interface has to be installed on the system where you run this function. You can download the VMware vSphere Command-Line Interface from: http://communities.vmware.com/community/vmtn/server/vsphere/automationtools/vsphere_cli?view=overview .EXAMPLE Add-vCLIfunction Adds all the VMware vSphere Command-Line Interface perl scripts as PowerCLI functions to your PowerCLI session. .COMPONENT VMware vSphere PowerCLI .NOTES Author: Robert van den Nieuwendijk Date: 21-07-2011 Version: 1.0 #> process { # Test if VMware vSphere Command-Line Interface is installed If (-not (Test-Path -Path "$env:ProgramFiles\VMware\VMware vSphere CLI\Bin\")) { Write-Error "VMware vSphere CLI should be installed before running this function." } else { # Add all the VMware vSphere CLI perl scripts as PowerCLI functions Get-ChildItem -Path "$env:ProgramFiles\VMware\VMware vSphere CLI\Bin\*.pl" | ForEach-Object { $Function = "function global:$($_.Name.Split('.')[0]) { perl '$env:ProgramFiles\VMware\VMware vSphere CLI\bin\$($_.Name)'" $Function += ' $args }' Invoke-Expression $Function } } } }
Step 4: Execute getluns.ps1 (. .\getluns.ps1)
#Initialize variables #Replace [INSERT VCENTER SERVER NAME] with your vCenter server name, leave preceding and and trailing " $VCServer = "[INSERT VCENTER SERVER NAME]" $objLuns = @() $objRDMs = @() #Connect to vCenter Server Connect-VIServer $VCServer $clusters = Get-cluster foreach ($cl in $clusters) { $clv = $cl | Get-View if ($clv.Host.count -gt 0) { #assume that all ESX hosts see the same luns $vmhost = get-view $clv.host[0] #Get ScsiLuns except local storage $ScsiLuns = $vmhost.Config.StorageDevice.ScsiLun | ? {$_.canonicalname -notmatch "vmhba0"} #Get Datastore volumes $Datastores = $vmhost.Config.FileSystemVolume.MountInfo foreach ($Lun in $ScsiLuns) { #Define Custom object $objVolume = "" | Select ClusterName,LunName,LunUuid,Lunsize,VolumeName #Add porperties to the newly created object $objVolume.ClusterName = $clv.Name $objVolume.LunName = $Lun.CanonicalName $objVolume.LunUuid = $Lun.Uuid $objVolume.LunSize = $Lun.Capacity.Block * $Lun.Capacity.BlockSize / 1GB foreach ($vol in $Datastores | % {$_.volume}) { if ($vol.extent | % {$_.diskname -eq $Lun.CanonicalName}) { $objVolume.VolumeName = $vol.Name } } $objLuns += $objVolume } } #RDM information $vms = $cl | Get-VM | Get-View if ($null -ne $vms) { foreach($vm in $vms){ foreach($dev in $vm.Config.Hardware.Device){ if(($dev.gettype()).Name -eq "VirtualDisk"){ if(($dev.Backing.CompatibilityMode -eq "physicalMode") -or ($dev.Backing.CompatibilityMode -eq "virtualMode")){ $rdm = "" | select VMName, LunUuid, DiskLabel $rdm.VMName = $vm.Name $rdm.LunUuid = $dev.Backing.LunUuid $rdm.DiskLabel = $dev.DeviceInfo.Label $objRDMs += $rdm } } } } } } foreach ($rdm in $objRDMs) { foreach ($disk in $objLuns) { if ($disk.LunUuid -eq $rdm.LunUuid) {$disk.VolumeName = $rdm.VMName + "/" + $rdm.DiskLabel} } } $objLuns | export-csv "scsiluns.csv" -notypeinformation -useculture Disconnect-VIServer -Confirm:$false
Step 5: Execute mpath.ps1 (. .\mpath.ps1)
Add-vCLIfunction $env:VI_USERNAME="root" $env:VI_PASSWORD="password" $result = foreach($esx in Get-VMHost){ esxcfg-mpath -l --server $esx.Name | %{ if($_.Length -gt 0){ if($_.Contains(': ')){ $temp = $_.Split(":") $desc = $temp[0].trim(0) $value = $temp[1..50] -join ":" Add-Member -InputObject $obj -Name $desc.trim() -Value $value.trim() -MemberType NoteProperty } else{ $obj = New-Object PSObject -Property @{ VMHost = $esx.Name Name = $_ } } } else{ $obj } } $obj } $result | export-csv "mpath.csv" -notypeinformation -useculture
Step 6: Get SP collect from EMC CLARiiON / VNX array
At this point you should have all the data required to map the RDM volumes on the DR side. I simply import the two CSVs generated by the scripts into excel (scsiluns.csv, mpath.csv) as well as the LUNs tab from the SP Collect (cap report).
Using Excel and some simple vlookups with the data gathered above you can create a table that looks like the following:
I could probably combine these three scripts into one but under a time crunch so just needed the data, maybe I will work on that at a later date or maybe someone can do it and share with me.