Automation

 View Only
Expand all | Collapse all

Script to add disk on multiple VMs and sharing with other VMs.

  • 1.  Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 01, 2022 12:19 PM

    Hi All,

    I am building a 6 node cluster. I have 6 VMs acting as cluster node. I have to add 10 disk on 1 VM and then I need to shared that disk among other 5 Node vms. Like I add 10 new HDD on Node 1 and once disk created then I am adding the same disk which I created on Node 1 with Other 5 nodes so that the disk can be shared for MS cluster.

    I am adding all the disk on Scsi controller 1 which config set as VMParavirtual and Bus Sharing as Physical.

    Can some one please help me with a code where I can automate it using a input file which will be having VM names.



  • 2.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 01, 2022 11:28 PM

    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
    }
    
    
    

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     



  • 3.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 02, 2022 05:35 AM

    Hi ,

     

    I am using below simple code to add the disk and then to share with other cluster node server.

    This below code is I am using to add disk. But here I wanted to put a input file which will be having all the node so that it can create the disk as mention in the code to all nodes.

     

    Connect-VIServer vcenter01.local
    $VM = get-vm -name node1

    New-HardDisk -VM $VM -CapacityGB 50 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -CapacityGB 50 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -CapacityGB 80 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -CapacityGB 20 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -CapacityGB 20 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"

     

    This 2nd code I am using to sharing the disk which were created using 1st code to other nodes so that the disk can be shared for SQL cluster. Here I have to change the server name every time like node2, node3, node4, node5, and I am looking the code to pick up server name from a input file 

     

    Connect-VIServer vcenter01.local
    $VM = get-vm -name node2

    New-HardDisk -VM $VM -DiskPath "[Datastore1] node1/node_1.vmdk" -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -DiskPath "[Datastore1] node1/node_2.vmdk" -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -DiskPath "[Datastore1] node1/node_3.vmdk" -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -DiskPath "[Datastore1] node1/node_4.vmdk" -Controller "SCSI Controller 1"
    New-HardDisk -VM $VM -DiskPath "[Datastore1] node1/node_5.vmdk" -Controller "SCSI Controller 1"

     

     

     



  • 4.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 02, 2022 08:12 AM

    I tried to modify the code to input a file with server name. but its not stopping after creating the mention disk, its looping again and creating the mention disk again and again. Pls can any one help what wrong I am doing here.

     

    $vms = Get-Content F:\JK\Add-Disk-Script\servers.txt

    foreach($VMname in $vms)

    {

    Get-VM $vms | New-HardDisk -CapacityGB 1 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"
    Get-VM $vms | New-HardDisk -CapacityGB 1.1 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"
    Get-VM $vms | New-HardDisk -CapacityGB 1.2 -Datastore "Datastore1" -StorageFormat EagerZeroedThick -Controller "SCSI Controller 1"


    }



  • 5.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 02, 2022 09:10 AM

    Hi, 

    I thought I understood that you wanted to set up a Microsoft Cluster Services (MSCS, WSFC), am I wrong?
    Because in this case, if you want to make a cluster with more than one machine, you have to go through the RDMs or the VVOLS. For vvols this is what I think I understand from the documentation.

    https://docs.vmware.com/en/VMware-vSphere/6.7/vsphere-esxi-vcenter-server-67-setup-mscs.pdf

     

    ObjectifDubai_0-1648890214872.png

     

    ObjectifDubai_0-1648890733841.png

     

     

     

    Otherwise, In the article below we also talk about vmdk sharing but in a vSan infrastructure for "RAC Oracle" or Redhat clusters

    https://blogs.vmware.com/virtualblocks/2019/12/19/eager-zeroed-thick-requirement-multi-writer-disks-removed-vsan-datastore/ 

     

     

     

     

     

     



  • 6.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 02, 2022 09:22 AM

    Hi, 

    Your code does not loop to infinity, but with each iteration you try to add the disks to all the vms

    Because you make a "Get-VM $vms"

    instead of a "Get-vm $VMname"



  • 7.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 02, 2022 02:25 PM

    Hi,

    Yes I am using vvol for ms cluster. I tried to add get-vm $VMName and ran the code again. It is adding only 1 disk on vm and through this error. please can you help.

    system_noida_0-1648909489214.png

     



  • 8.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 02, 2022 08:13 PM

    Some tracks:
    - Have you configured the SCSI cards correctly?

    https://blogs.vmware.com/virtualblocks/2018/05/31/scsi-3-vvols/


    - When we create a Microsoft cluster with several vm, For the 1st VM we create disk volumes, for the other vms we mount an already existing disk so the procedure is not the same. In addition, a shared disk in a Microsoft cluster must be positioned on all vms on the same controller and the same port.

    --> Are your vms on? If yes, stop your vms to add the shared volumes

     

     



  • 9.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 03, 2022 08:32 AM

    yes, I have configure the scsi controller correctly on all nodes. I have only put 1 node in the input file. If I put 1 disk create code i.e New-HardDisk ..... then there is no error , but when i am putting multiple code to create more than one disk then its giving that error. I suspect that this error show when there is already a task is running on the vm and you are trying to run another task. Like its already busy creating 1 disk but the powercli pushing the code to create other disk also. This is what I suspect. May be some kind of wait code can help here. like the code should create disk one by on after completing first. any though and help pls



  • 10.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 03, 2022 10:13 AM

    Hi, 

    No, because adding a disk is not done asynchronously, the New-HardDisk cmdlet only returns you once the action is complete.

    Are your vms already on vvol?

    Could you put a screenshot of the configuration in vSphere of one of your SCSI controllers and of the disk that was added by the PowerCli command?



  • 11.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 03, 2022 10:35 AM

    Hi,

    Here is the screen shot below. I ran the below code again and got this error while the code add 2nd and 3rd HDD.

    system_noida_2-1648982068462.png

     

     

     

    new Hard disk added screen shot

    system_noida_0-1648981823979.png

    ISCI Controller setting

    system_noida_1-1648981863820.png

     

     



  • 12.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 03, 2022 01:09 PM

    hi,

    To see if we have more information, could you add to your new-harddisk command the -verbose option

    On the other hand, when we read the errors we understand that the error also appears on the addition of the 1st disk



  • 13.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 03, 2022 02:51 PM

    Hello,

    Could you change the SCSI Bus Sharing of your controller by placing it on "Virtual", I think you will no longer have any errors.

    I think you are trying to add a classic virtual disk to a controller that expects a physical-type volume, which results in an error.

     



  • 14.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 04, 2022 05:11 AM

    Hi ,

    It was an issue with the powershell ISE windows. I did closed it and open again and ran the same code and this time there is no error and all disk created successful. Even I have not changed the SCSI controller setting to Virtual, It is still Physical.

     

    Thank you very much for helping me on this

     



  • 15.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 04, 2022 07:49 AM

    Hi,

    So now the adding disk using the code is working fine. now I wanted to add the partition and drive letter remotely on the nodes using the powershell. I found a code on google and I have modified it as per my requirement. using the below code I wanted to achieve this ....

    1. Get the nodes from a input file
    2. Find out the offline disk and make them online.
    3. Find the online RAW disk and initialize them using GPT partition.
    4. Create a partition of disk 1 with a volume level and assign a drive latter
    5. Create all required folders into the drive created point #3, I will be using those folder as mount point wit other disks.
    6. Cretae the partition for the other disk and use the folders as mount point with no drive letter and assign the full folder path as volume label

    Till point#5 the code is working fine. but when it come to point#6 to create partition of other disk and make them as mount point, I am getting the below error. Please can someone help me here to achieve what I am looking for.

     

    #1. Get the nodes from a input file

    $vms = Get-Content "F:\Jeetu\Add-Disk-Script\servers.txt"

    foreach ($VMname in $vms) {}

    #2. Find out the offline disk and make them online.
    Invoke-Command -ComputerName $VMname -ScriptBlock { get-disk | where operationalstatus -eq Offline | Set-Disk -IsOffline:$false }

    #3. Find the online RAW disk and initialize them using GPT partition.
    Invoke-Command -ComputerName $VMname -ScriptBlock { get-disk | where PartitionStyle -eq RAW | Initialize-Disk -PartitionStyle GPT }

    #4. Create a partition of disk 1 with a volume level and assign a drive latter. Check Disk Number Manually.

    Invoke-Command -ComputerName $VMname -ScriptBlock { New-Partition -DiskNumber 2 -UseMaximumSize }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Get-Partition –Disknumber 2 –PartitionNumber 2 | Format-Volume –FileSystem NTFS –NewFileSystemLabel TESTSQLDB001 –Confirm:$false }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Get-Partition -DiskNumber 2 -PartitionNumber 2 | Set-Partition -NewDriveLetter L }

    #5. Create all required folders into the drive created point, I will be using those folder as mount point with other disks.
    Invoke-Command -ComputerName $VMname -ScriptBlock { mkdir L:\TESTSQLDB001 }
    Invoke-Command -ComputerName $VMname -ScriptBlock { mkdir L:\TESTSQLDB001\Data }
    Invoke-Command -ComputerName $VMname -ScriptBlock { mkdir L:\TESTSQLDB001\Backup }

    #6. Cretae the partition for the other disk and use the folders as mount point with no drive letter and assign the full folder path as volume label
    Invoke-Command -ComputerName $VMname -ScriptBlock { New-Partition -DiskNumber 3 -UseMaximumSize }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Add-PartitionAccessPath -DiskNumber 3 -PartitionNumber 3 –AccessPath L:\TESTSQLDB001\Data }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Get-Partition –Disknumber 3 –PartitionNumber 3 | Format-Volume –FileSystem NTFS –NewFileSystemLabel "L:\TESTSQLDB001\Data" –Confirm:$false }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Get-Partition -DiskNumber 3 -PartitionNumber 3 | Set-Partition -NoDefaultDriveLetter:$True }

    Invoke-Command -ComputerName $VMname -ScriptBlock { New-Partition -DiskNumber 4 -UseMaximumSize }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Add-PartitionAccessPath -DiskNumber 4 -PartitionNumber 4 –AccessPath "L:\TESTSQLDB001\Backup" }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Get-Partition –Disknumber 4 –PartitionNumber 4 | Format-Volume –FileSystem NTFS –NewFileSystemLabel "L:\TESTSQLDB001\Backup" –Confirm:$false }
    Invoke-Command -ComputerName $VMname -ScriptBlock { Get-Partition -DiskNumber 4 -PartitionNumber 4 | Set-Partition -NoDefaultDriveLetter:$True }


    }

     

    system_noida_0-1649058529210.png

     



  • 16.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 04, 2022 10:13 AM

    Its fixed. I was putting wrong partition number . I should put partition number as 2 . After i changed it to 2 , its working now.

    Is there any way I can reduce the changing of disk number everywhere pls? Partition number will remain 2 on each disk , but I have to change the disk number each point. any way to reduce it pls



  • 17.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 05, 2022 04:26 AM

    please can someone help with the code to reduce the putting the disk number each place with my above code I am using to create the partition and mount point inside a node remotely.



  • 18.  RE: Script to add disk on multiple VMs and sharing with other VMs.

    Posted Apr 06, 2022 08:56 AM

    Hi   .  Please would you be able to help me here on my above requirement .