Hi,
A few months ago I researched to write a script that allowed me to configure the vms of a SQL cluster by mapping the RDMs to the SCSI controllers 1,2 and 3
I tried below to put you the Important elements
Step 1 :
I have a file containing the following information regarding RDMs
/vmfs/devices/disks/naa.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe160
/vmfs/devices/disks/naa.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe161
/vmfs/devices/disks/naa.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe162
/vmfs/devices/disks/naa.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe163
Beginning of the Script :
#Traitement des arguments de ligne de commande
param(
[parameter(Mandatory=$true)][string]$server ,
[parameter(Mandatory=$false)][string]$user,
[parameter(Mandatory=$false)][string]$password,
[Parameter(Mandatory=$true)][string]$vmprincipal, # Name of the vm to which you added the RDMs
[Parameter(Mandatory=$true)][string[]]$vmsecondaire, # Name of other VMs to which you want to map the RDMs
[Parameter(Mandatory=$true)][string]$datastore, # name of the datastore on which you want to position the RDM pointers
[Parameter(Mandatory=$true)][string]$pathRDM # path of the file containing the list of RDMs
)
I didn't put the vCenter connection string below, but don't forget to add it using the Server, User and password parameters
if( ($($vmprincipal) -match "[*]+") -or ($($vmsecondaire) -match "[*]+") ){
Write-host "The use of the character * in the name of a vm is prohibited"
exit;
}
# We build one Array with the name of all Vms
$nameVMs+=$vmprincipal.replace(' ' , '')
foreach($element in $vmsecondaire){
$nameVMs+=$element.replace(' ' , '')
}
# We build one Array with the list of RDMs to attach
foreach($element in (get-content -Path $pathRDM )){
$listRDM+=$element.replace(' ' , '')
}
# --------------------------------------------------------------------------------
#
# We start by stopping the vms that are started
#
get-vm -Name $nameVMs | %{
if($_.PowerState -eq "PoweredOn"){
if($_.ExtensionData.Guest.ToolsRunningStatus -eq "guestToolsRunning"){
# If the tools are started
$_ | Shutdown-VMGuest -Confirm:$false
}else{
$_ | stop-vm -Confirm:$false
}
}
}
# We are waiting for the shutdown of the VMs
$continue=$true
while($continue){
if((get-vm -name $nameVMs | select PowerState) -match "PoweredOn"){
Start-sleep 2;
write-host "." -NoNewline
}else{
$continue=$false
}
}
#
#
# --------------------------------------------------------------------------------------------------------------------------
#
# 1 - We delete the old Disks on the SCSI Controllers SCSI 1,2 et 3
# We only keep on the vms the disks on controller 0 --> where the System disk is located
foreach($nameVM in $nameVMs){
Get-HardDisk -VM $nameVM | %{
if( ($_ | Get-ScsiController).ExtensionData.busNumber -gt 0){
$_ | Remove-HardDisk -DeletePermanently -Confirm:$false
}
}
}
#
#
# --------------------------------------------------------------------------------------------------------------------------
#
# 2 - we remove the old SCSI controllers 1,2 and 3
# https://www.reddit.com/r/PowerShell/comments/8svpp7/powercli_remove_a_scsi_controller/
# https://communities.vmware.com/t5/VMware-PowerCLI-Discussions/Remove-SCSIController/td-p/439789
#
# Normally when deleting disks the unused SCSI controllers will also be deleted!!!!
#
foreach($nameVM in $nameVMs){
$nbControllerScsi=(Get-ScsiController -VM $nameVM).count
Write-Host " --> Nombre de controller Scsi : $($nbControllerScsi)"
foreach ($a_ScsiController in (get-vm -name $nameVM | Get-ScsiController | WHERE{$_.ExtensionData.BusNumber -gt 0 }))
{
$VM = $a_ScsiController.Parent.ExtensionData
'{0} - Removing Paravirtual SCSIController, Bus Number: {1}' -f $VM.Name,$BusNumber | Write-Verbose
$storagespec = New-Object VMware.Vim.VirtualMachineConfigSpec
$removeSCSIDevice = New-Object VMware.Vim.VirtualDeviceConfigSpec
$removeSCSIDevice.operation = "remove"
$removeSCSIDevice.device = $a_ScsiController.ExtensionData
$storageSpec.deviceChange = $removeSCSIDevice
$shouldText = '{0}, VM {1}' -f $a_ScsiController.Name,$a_ScsiController.Parent.Name
$a_ScsiController.Parent.ExtensionData.ReconfigVM($storageSpec)
}
}
#
#
# --------------------------------------------------------------------------------------------------------------------------
#
# 3 - We create the SCSI Controllers 1,2 et 3
#
$ControllerType='ParaVirtualSCSIController' #'ParaVirtualSCSIController','VirtualBusLogicController','VirtualLsiLogicController','VirtualLsiLogicSASController'
$SharedBus='physicalSharing' #'noSharing', 'physicalSharing', 'virtualSharing
foreach($nameVM in $nameVMs){
$vm=Get-View -Id (get-vm -name $nameVM).Id
foreach($BusNumber in 1..3){
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$spec.DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (1)
$spec.DeviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec
$spec.DeviceChange[0].Device = New-Object VMware.Vim.$ControllerType
$spec.DeviceChange[0].Device.SharedBus = $SharedBus
$spec.DeviceChange[0].Device.DeviceInfo = New-Object VMware.Vim.Description
$spec.DeviceChange[0].Device.DeviceInfo.Summary = 'New SCSI controller'
$spec.DeviceChange[0].Device.DeviceInfo.Label = 'New SCSI controller'
$spec.DeviceChange[0].Device.BusNumber = $BusNumber
$spec.DeviceChange[0].Operation = 'add'
LogAndShow -text "Ajout Controller $($BusNumber) - $($ControllerType) - $($SharedBus)" -color $msg_color_info
[void]$vm.ReconfigVM_Task($spec)
Start-Sleep -Seconds 3
}
}
#
#
# --------------------------------------------------------------------------------------------------------------------------
#
# 4 - Added RDMs to the first Vm
# By distributing the RDMs on controllers 1,2 and 3
$scsci=0
foreach($element in $listRDM){
$numController=($scsci%3)+1
$Controller="SCSI Controller $numController"
get-vm -name $vmprincipal | New-HardDisk -Controller "$($Controller)" -DiskType RawPhysical -DeviceName "$($element)" -Datastore "$($datastore)"
$scsci=$scsci+1
}
#
#
# --------------------------------------------------------------------------------
#
# 5 - we add the disks to the other VMs by relying on the 1st VM. This allows us to mount the RDMs on the same SCSI Port
Get-VM -name $vmprincipal | Get-HardDisk | %{
$scsibusnumber=(Get-ScsiController -HardDisk $_).ExtensionData.BusNumber
if($scsibusnumber -gt 0){
$unitnumber = $_.ExtensionData.UnitNumber
$datastorepath = $_.FileName
foreach($nameVM in $vmsecondaire){
$vm = Get-VM -Name $nameVM
# Does the SCSI Controller exist?
$controller = Get-ScsiController -VM $vm.name | where{$_.ExtensionData.BusNumber -eq $scsibusnumber}
# Add the VMDK
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$device = New-Object VMware.Vim.VirtualDisk
$device.Backing = New-Object VMware.Vim.VirtualDiskRawDiskMappingVer1BackingInfo
$device.Backing.Filename = $datastorepath
$device.UnitNumber = $unitnumber
$device.Backing.DiskMode = 'independent_persistent'
$device.ControllerKey = $controller.ExtensionData.Key
$device.Key = -10
$devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
$devChange[0].Device = $device
$devChange[0].Operation = 'add'
$spec.DeviceChange += $devChange
$vm.ExtensionData.ReconfigVM($spec)
}
}
}
#
# 6 - Start VMs
#
#
get-vm -name $nameVMs | %{
$_ |Start-VM
}