VMware Cloud Community
JP112
Contributor
Contributor
Jump to solution

Script for attaching multiple existing disk to VM with specific scsi bus number and device number from CSV

Hello,

I was trying to attach multiple vmdk with specific scsi bus number and device number using import-csv method and onyx tools generated code,

Looks like it keep failed and  don't able add scsi bus number and associate device number, i have attached CSV for reference

#File Path

$csvpath = "C:\Users\Desktop\Final\TESt0001.csv"

$vmlist = Import-CSV -path $csvpath

# map the Variables

foreach ($item in $vmlist) {

$vmname = $item.vmname

$vmdk = $item.datastorepath

$busnumber = $item.SCSIBUSNUMBER

$unitnumber = $item.UNITNUMBER

$vm = Get-VM $vmname

Write-Host “Adding Disk “$vmdk” to “$vm” at SCSI ID “$busnumber”:”$unitnumber

$ctrll = Get-ScsiController -VM $vm | ?{$_.extensiondata.busNumber -eq $busnumber}

Write-Host “Controller Key “$ctrll.extensiondata.key

$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].operation = “add”

$spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDisk

$spec.deviceChange[0].device.key = -100

$spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo

$spec.deviceChange[0].device.backing.fileName = “”+$vmdk

$spec.deviceChange[0].device.backing.diskMode = “persistent”

$spec.deviceChange[0].device.connectable = New-Object VMware.Vim.VirtualDeviceConnectInfo

$spec.deviceChange[0].device.controllerKey = [int]$ctrll.extensiondata.Key

$spec.deviceChange[0].device.unitNumber = [int]$unitNumber

$spec.extraConfig = New-Object VMware.Vim.OptionValue[] (1)

$spec.extraConfig[0] = New-Object VMware.Vim.OptionValue

$spec.extraConfig[0].key = “scsi” + $busnumber + “:” + $unitnumber

$vm.ExtensionData.ReconfigVM($spec)

}

Error:

Exception calling "ReconfigVM" with "1" argument(s): "The device '0' is referring to a nonexisting controller '0'."

At line:50 char:1

+ $vm.ExtensionData.ReconfigVM($spec)

+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

    + FullyQualifiedErrorId : VimException

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

I started from scratch, and added the missing controller functionality.

Try something like this, but note that I took simple controllers and minimal harddisk settings.

Those can be changed by setting/changing properties in the specifications.

$csvpath = "C:\Users\Desktop\Final\TESt0001.csv"

foreach($vmdk in (Import-CSV -Path $csvpath -UseCulture)){

    $vm = Get-VM -Name $vmdk.vmname

    # Does the SCSI Controller exist?

    $controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}

    while(-not $controller){

       $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

       $device = New-Object VMware.Vim.VirtualLsiLogicController

       $device.BusNumber = $vmdk.SCSIBUSNUMBER

       $device.Key = -1

       $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

       $devChange.Device = $device

       $devChange.Operation = 'add'

       $spec.DeviceChange += $devChange

       $vm.ExtensionData.ReconfigVM($spec)

       $controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}

    }

    # Add the VMDK

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $device = New-Object VMware.Vim.VirtualDisk

    $device.Backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo

    $device.Backing.Filename = $vmdk.datastorepath

    $device.UnitNumber = $vmdk.UNITNUMBER

    $device.Backing.DiskMode = '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)

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
31 Replies
LucD
Leadership
Leadership
Jump to solution

Are you sure SCSI Controllers 1 and 2 exist on the VM?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
JP112
Contributor
Contributor
Jump to solution

Hi LuC,

Thank you for quick reply as always Smiley Happy, SCSI Controllers 1 and 2 does not exist on the VM and i thought it will created by itself from reading bus number from CSV,

Is there anyway we can specify in script to add new scsi controller when it's device/bus id are like "2:8" and scsi controller are does not exit on VM ?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

No, that script doesn't add the SCSI controllers when they are missing.

There is a sample somewhere in this forum where the SCSI controllers are added if they do not exist.

Have a look at Re: Add new SCSI controller and new disk - powershell SDK


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
JP112
Contributor
Contributor
Jump to solution

Thanks Luc for your Help Smiley Happy, i have created separate script to add new scsi controller to all VM ( thanks to Onyx), i'm wondering where can  i merge this script to my original script

$vmlist = Import-CSV -path C:\Users\Desktop\Final\vmlist.csv

foreach ($item in $vmlist) {

$vmname = $item.vmname

$vm = Get-VM $vmname

Write-Host “Adding SCSI Contoller" to "$vmname"

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$spec.deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec[] (3)

$spec.deviceChange[0] = New-Object VMware.Vim.VirtualDeviceConfigSpec

$spec.deviceChange[0].operation = 'add'

$spec.deviceChange[0].device = New-Object VMware.Vim.ParaVirtualSCSIController

$spec.deviceChange[0].device.hotAddRemove = $true

$spec.deviceChange[0].device.busNumber = 1

$spec.deviceChange[0].device.deviceInfo = New-Object VMware.Vim.Description

$spec.deviceChange[0].device.deviceInfo.summary = ''

$spec.deviceChange[0].device.deviceInfo.label = 'New SCSI controller'

$spec.deviceChange[0].device.sharedBus = 'noSharing'

#$spec.deviceChange[0].device.key = -104

$spec.deviceChange[1] = New-Object VMware.Vim.VirtualDeviceConfigSpec

$spec.deviceChange[1].operation = 'add'

$spec.deviceChange[1].device = New-Object VMware.Vim.ParaVirtualSCSIController

$spec.deviceChange[1].device.hotAddRemove = $true

$spec.deviceChange[1].device.busNumber = 2

$spec.deviceChange[1].device.deviceInfo = New-Object VMware.Vim.Description

$spec.deviceChange[1].device.deviceInfo.summary = ''

$spec.deviceChange[1].device.deviceInfo.label = 'New SCSI controller'

$spec.deviceChange[1].device.sharedBus = 'noSharing'

#$spec.deviceChange[1].device.key = -105

$spec.deviceChange[2] = New-Object VMware.Vim.VirtualDeviceConfigSpec

$spec.deviceChange[2].operation = 'add'

$spec.deviceChange[2].device = New-Object VMware.Vim.ParaVirtualSCSIController

$spec.deviceChange[2].device.hotAddRemove = $true

$spec.deviceChange[2].device.busNumber = 3

$spec.deviceChange[2].device.deviceInfo = New-Object VMware.Vim.Description

$spec.deviceChange[2].device.deviceInfo.summary = ''

$spec.deviceChange[2].device.deviceInfo.label = 'New SCSI controller'

$spec.deviceChange[2].device.sharedBus = 'noSharing'

#$spec.deviceChange[2].device.key = -106

#$_this = Get-View -Id 'VirtualMachine-vm-517'

#$vm.ReconfigVM_Task($spec)

$vm.ExtensionData.ReconfigVM($spec)

}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I started from scratch, and added the missing controller functionality.

Try something like this, but note that I took simple controllers and minimal harddisk settings.

Those can be changed by setting/changing properties in the specifications.

$csvpath = "C:\Users\Desktop\Final\TESt0001.csv"

foreach($vmdk in (Import-CSV -Path $csvpath -UseCulture)){

    $vm = Get-VM -Name $vmdk.vmname

    # Does the SCSI Controller exist?

    $controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}

    while(-not $controller){

       $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

       $device = New-Object VMware.Vim.VirtualLsiLogicController

       $device.BusNumber = $vmdk.SCSIBUSNUMBER

       $device.Key = -1

       $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

       $devChange.Device = $device

       $devChange.Operation = 'add'

       $spec.DeviceChange += $devChange

       $vm.ExtensionData.ReconfigVM($spec)

       $controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}

    }

    # Add the VMDK

    $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

    $device = New-Object VMware.Vim.VirtualDisk

    $device.Backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo

    $device.Backing.Filename = $vmdk.datastorepath

    $device.UnitNumber = $vmdk.UNITNUMBER

    $device.Backing.DiskMode = '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)

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
JP112
Contributor
Contributor
Jump to solution

Work like charm !! Thank you very much Luc Smiley Happy  this is exactly what i'm trying to get done, much appreciated

Reply
0 Kudos
senseyk
Contributor
Contributor
Jump to solution

Hi,

how can i do if for this section of the script:

$device.Backing.Filename = $vmdk.datastorepath

the Hdd isn't created yet.

The purpose is to create, assign to specific controller (busnumber and unit number) depend on what type of file the disk will store (Data, Logs, ... )

there is the code:

$VM = Get-VM -Name $VirtualMachine

            $controller = Get-ScsiController -VM $VirtualMachine | where{$_.ExtensionData.BusNumber -eq $BusNumber}

            while(-not $controller){

               $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

               $device = New-Object VMware.Vim.VirtualLsiLogicController

               $device.BusNumber = $BusNumber

               $device.Key = -1

               $devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

               $devChange.Device = $device

               $devChange.Operation = 'add'

               $spec.DeviceChange += $devChange

               $vm.ExtensionData.ReconfigVM($spec)

               $controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $BusNumber}

            }

            # Add the VMDK

            $spec = New-Object VMware.Vim.VirtualMachineConfigSpec

            $device = New-Object VMware.Vim.VirtualDisk

            $device.Backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo

            $device.Backing.Filename = $vmdk.datastorepath

            $device.UnitNumber = $UnitNumb

            $device.Backing.DiskMode = '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)

Reply
0 Kudos
Sudi80
Contributor
Contributor
Jump to solution

I god the Error as below

Get-ScsiController : Cannot validate argument on parameter 'VM'. The argument is null. Provide a valid value for the argument, and then try running the command again.

At C:\Users\A707579a\Desktop\RDM_A.ps1:42 char:45

+        $controller = Get-ScsiController -VM $vm | where{$_.ExtensionD ...

+                                             ~~~

    + CategoryInfo          : InvalidData: (:) [Get-ScsiController], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.VirtualDevice.GetScsiController.

I saved the content in CSV and please find the content

vmname                                              datastorepath                                                                       SCSIBUSNUMBER UNITNUMBER

cskpcloudxp2072_CHG0149340 [NDCVB4-TSD001] cskpcloudxp2052/cskpcloudxp2052_4.vmdk 1                               1

cskpcloudxp2072_CHG0149340 [NDCVB4-TSD001] cskpcloudxp2052/cskpcloudxp2052_5.vmdk 1                                2

cskpcloudxp2072_CHG0149340 [NDCVB4-TSD001] cskpcloudxp2052/cskpcloudxp2052_6.vmdk 1                                   3.

Please do the needful.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Could it be that you have a blank line in the CSV?
At the end perhaps?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Sudi80
Contributor
Contributor
Jump to solution

Script is running but i dont see the modifications.

Can you help me as we have 32 RDMs per VMs

Let me know so that I will share the screen now... Will it be ok now.

Reply
0 Kudos
cajemac
Contributor
Contributor
Jump to solution

superb, this script helped me to add as per expectation.

Could you also share the script to remove/detach also... thanks

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Isn't the Remove-HardDisk cmdlet doing that?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
cajemac
Contributor
Contributor
Jump to solution

thank. i was checking its example.

$hdd = Get-HardDisk -VM 'MyVM' -Name 'Hard disk 4' Remove-HardDisk -HardDisk $hdd

 

is there any was by which i can call the inputs from csv file & detach disk from VM

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

If that CSV file contains the name of the VM and the name of the HardDisk, that should not be a problem.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
bikashyadav
Contributor
Contributor
Jump to solution

Hi LucD,

How do i incorporate the below items post addition of the existing disks.i.e post the disks are added how do i modify the below parameters using the same script?

$device.Backing.DiskMode = $vmdk.Persistence

$device.device.Backing.Sharing = $vmdk.MultiWriter

Thanks

Bikash

Reply
0 Kudos
bikashyadav
Contributor
Contributor
Jump to solution

Hi LucD,

Below is the script i am using. Everything works fine. But when i add the multiwriter option it gives the below error in screenshot.

$csvpath = "D:\TestVM-Multiwriter.csv"

foreach($vmdk in (Import-CSV -Path $csvpath -UseCulture)){

$vm = Get-VM -Name $vmdk.vmname

# Does the SCSI Controller exist?

$controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}

while(-not $controller){

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$device = New-Object VMware.Vim.VirtualLsiLogicController

$device.BusNumber = $vmdk.SCSIBUSNUMBER

$device.Key = -1

$devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec

$devChange.Device = $device

$devChange.Operation = 'add'

$spec.DeviceChange += $devChange

$vm.ExtensionData.ReconfigVM($spec)

$controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}

}

# Add the VMDK

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$device = New-Object VMware.Vim.VirtualDisk

$device.Backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo

$device.Backing.Filename = $vmdk.datastorepath

$device.UnitNumber = $vmdk.UNITNUMBER

$device.Backing.DiskMode = 'Independent_Persistent'

$device.Backing.Sharing = 'sharingMultiWriter'

$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)

}

 

bikashyadav_0-1621795681254.png

Thanks

Bikash

Reply
0 Kudos
mlgurav
Contributor
Contributor
Jump to solution

I am getting below error when running the script.

 

Exception calling "ReconfigVM" with "1" argument(s): "Incompatible device backing specified for device '0'."
At D:\Cloud_Sync\gDrive_mgvmlabs\SYNC\scripts\vmware\ReAttachExistingDisks\ReAattachExistingDisks.ps1:31 char:5
+ $vm.ExtensionData.ReconfigVM($spec)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : VimException

 

My script is as below:

$csvpath = "D:\Cloud_Sync\gDrive_mgvmlabs\SYNC\scripts\vmware\ReAttachExistingDisks\disks.csv"
foreach($vmdk in (Import-CSV -Path $csvpath -UseCulture)){
$vm = Get-VM -Name $vmdk.vmname
# Does the SCSI Controller exist?
$controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}
while(-not $controller){
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$device = New-Object VMware.Vim.VirtualLsiLogicController
$device.BusNumber = $vmdk.SCSIBUSNUMBER
$device.Key = -1
$devChange = New-Object VMware.Vim.VirtualDeviceConfigSpec
$devChange.Device = $device
$devChange.Operation = 'add'
$spec.DeviceChange += $devChange
$vm.ExtensionData.ReconfigVM($spec)
$controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}
}
# Add the VMDK
$spec = New-Object VMware.Vim.VirtualMachineConfigSpec
$device = New-Object VMware.Vim.VirtualDisk
$device.Backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo
$device.Backing.Filename = $vmdk.datastorepath
$device.UnitNumber = $vmdk.UNITNUMBER
$device.Backing.DiskMode = '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)
}

Reply
0 Kudos
leomahesh
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

Will below script work if the controller is already there. or Will I have to modify any other lines of the script. Also will it work for any number of rows from the csv file.

$csvpath = "C:\Users\Desktop\Final\TESt0001.csv"

foreach($vmdk in (Import-CSV -Path $csvpath -UseCulture)){

$vm = Get-VM -Name $vmdk.vmname

# Does the SCSI Controller exist?

$controller = Get-ScsiController -VM $vm | where{$_.ExtensionData.BusNumber -eq $vmdk.SCSIBUSNUMBER}


# Add the VMDK

$spec = New-Object VMware.Vim.VirtualMachineConfigSpec

$device = New-Object VMware.Vim.VirtualDisk

$device.Backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo

$device.Backing.Filename = $vmdk.datastorepath

$device.UnitNumber = $vmdk.UNITNUMBER

$device.Backing.DiskMode = '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)

}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

You will have to move the call to ReconfigVM outside the loop over all the VMDK.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos