MichaelW007
Enthusiast
Enthusiast

PowerCLI Script to add disk fails after upgrading to vSphere 5.5 U1 and PowerCLI 5.5 R2

Jump to solution

Hi All,

I've created the following script to add a disk to a VM in multi-writer mode for Oracle RAC. This script used to work on vSphere 5.5 GA and PowerCLI 5.5 GA, but now no longer works with vSphere 5.5 U1 and PowerCLI 5.5 R2. I'm not sure what exactly has changed but I suspect it's got something to do with the SCSI controller specification objects, specifically the controller key.

Connect-VIServer VC

$vmname = Read-Host "VM Name to add disks to"

$vmdk = Read-Host "Disk to Add (Full Path)"

$busnumber = Read-host "SCSI Bus Number Number"

$unitnumber = Read-Host "Disk Unit Number"

[int64]$capacity = Read-Host "Disk Capacity (GB)"

$vm = Get-VM $vmname

[int64]$capcitykb = ($capacity * 1Gb) / 1Kb

Write-Host "Creating New Disk " $vmdk " of size " $capacity " GB to " $vm " at SCSI ID " $busnumber ":" $unitnumber

Write-Host "Disk Capacity in KB "$capcitykb

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

Write-Host "Controller Key " $ctrll.extensiondata.controllerkey

$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].fileOperation = "create"

$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.thinProvisioned = $false

$spec.deviceChange[0].device.backing.split = $false

$spec.deviceChange[0].device.backing.writeThrough = $false

$spec.deviceChange[0].device.backing.eagerlyScrub = $true

$spec.deviceChange[0].device.backing.diskMode = "independent_persistent"

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

$spec.deviceChange[0].device.connectable.startConnected = $true

$spec.deviceChange[0].device.connectable.allowGuestControl = $false

$spec.deviceChange[0].device.connectable.connected = $true

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

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

$spec.deviceChange[0].device.capacityInKB = $capacitykb

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

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

$spec.extraConfig[0].key = "scsi" + $busnumber + ":" + $unitnumber + ".sharing"

$spec.extraConfig[0].value = "multi-writer"

$vm.ExtensionData.ReconfigVM($spec)

For some reason $ctrll.key no longer returns any value and is completely missing if I do a $ctrll | get-member to view the properties of the object.

Any advice on how to get this script working would be greatly appreciated.

Kind regards,

Michael

0 Kudos
1 Solution

Accepted Solutions
MichaelW007
Enthusiast
Enthusiast

Hi Luc,

Took a bit of debugging but I finally got the script to work. It looks like the values for $ctrll.key which I expected to be in the object are definitely gone. In order to find the correct value I need to now refer to $ctrll.extensiondata.key. Also I needed to cast the variables very carefully to the device spec. For the controllerKey it had to be cast to int, as did the unitNumber. Also found that the calculation for capacitykb had to be cast to int64 and the 1gb and 1kb had to be lowercase for some reason, else the value came back as zero. So a few weird things in 5.5 U1 that seem to possibly have messed up the API's. Here is the final script I've got that is working. It's not pretty, there is no validation or checks or anything, but it works.

Connect-VIServer VC

$vmname = Read-Host "VM Name to add disks to"

$vmdk = Read-Host "Disk to Add (Full Path)"

[int]$busnumber = Read-host "SCSI Bus Number Number"

[int]$unitnumber = Read-Host "Disk Unit Number"

$capacity = Read-Host "Disk Capacity (GB)"

$vm = Get-VM $vmname

[int64]$capcitykb = ($capacity * 1gb) / 1kb

Write-Host "Creating New Disk " $vmdk " of size " $capacity " GB to " $vm " at SCSI ID " $busnumber ":" $unitnumber

Write-Host "Disk Capacity in KB " $capcitykb

$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].fileOperation = "create"

$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.thinProvisioned = $false

$spec.deviceChange[0].device.backing.split = $false

$spec.deviceChange[0].device.backing.writeThrough = $false

$spec.deviceChange[0].device.backing.eagerlyScrub = $true

$spec.deviceChange[0].device.backing.diskMode = "independent_persistent"

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

$spec.deviceChange[0].device.connectable.startConnected = $true

$spec.deviceChange[0].device.connectable.allowGuestControl = $false

$spec.deviceChange[0].device.connectable.connected = $true

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

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

$spec.deviceChange[0].device.capacityInKB = $capacitykb

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

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

$spec.extraConfig[0].key = "scsi" + $busnumber + ":" + $unitnumber + ".sharing"

$spec.extraConfig[0].value = "multi-writer"

$vm.ExtensionData.ReconfigVM($spec)

Now I just need to check if the script I've got that attaches this disk to the other Oracle RAC nodes works.

View solution in original post

0 Kudos
6 Replies
LucD
Leadership
Leadership

Did you get any error messages ?


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

0 Kudos
MichaelW007
Enthusiast
Enthusiast

I get Invalid configuration for device '0'. But if I do a $ctrll.key it returns nothing. This used to work. So I'm not sure what to do now. I tried using extendiondata.controllerKey in it's place and that also doesn't work.

0 Kudos
MichaelW007
Enthusiast
Enthusiast

I've also just tried using $ctrll.extensiondata.key and that also fails with an invalid configuration for device '0' error message. So I'm out of ideas. Anything at all that might help would be greatly appreciated. Thanks for responding @LucD.

0 Kudos
MichaelW007
Enthusiast
Enthusiast

Hi Luc,

Took a bit of debugging but I finally got the script to work. It looks like the values for $ctrll.key which I expected to be in the object are definitely gone. In order to find the correct value I need to now refer to $ctrll.extensiondata.key. Also I needed to cast the variables very carefully to the device spec. For the controllerKey it had to be cast to int, as did the unitNumber. Also found that the calculation for capacitykb had to be cast to int64 and the 1gb and 1kb had to be lowercase for some reason, else the value came back as zero. So a few weird things in 5.5 U1 that seem to possibly have messed up the API's. Here is the final script I've got that is working. It's not pretty, there is no validation or checks or anything, but it works.

Connect-VIServer VC

$vmname = Read-Host "VM Name to add disks to"

$vmdk = Read-Host "Disk to Add (Full Path)"

[int]$busnumber = Read-host "SCSI Bus Number Number"

[int]$unitnumber = Read-Host "Disk Unit Number"

$capacity = Read-Host "Disk Capacity (GB)"

$vm = Get-VM $vmname

[int64]$capcitykb = ($capacity * 1gb) / 1kb

Write-Host "Creating New Disk " $vmdk " of size " $capacity " GB to " $vm " at SCSI ID " $busnumber ":" $unitnumber

Write-Host "Disk Capacity in KB " $capcitykb

$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].fileOperation = "create"

$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.thinProvisioned = $false

$spec.deviceChange[0].device.backing.split = $false

$spec.deviceChange[0].device.backing.writeThrough = $false

$spec.deviceChange[0].device.backing.eagerlyScrub = $true

$spec.deviceChange[0].device.backing.diskMode = "independent_persistent"

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

$spec.deviceChange[0].device.connectable.startConnected = $true

$spec.deviceChange[0].device.connectable.allowGuestControl = $false

$spec.deviceChange[0].device.connectable.connected = $true

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

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

$spec.deviceChange[0].device.capacityInKB = $capacitykb

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

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

$spec.extraConfig[0].key = "scsi" + $busnumber + ":" + $unitnumber + ".sharing"

$spec.extraConfig[0].value = "multi-writer"

$vm.ExtensionData.ReconfigVM($spec)

Now I just need to check if the script I've got that attaches this disk to the other Oracle RAC nodes works.

View solution in original post

0 Kudos
LucD
Leadership
Leadership

I was looking at it as well, but hadn't come that far yet.

Thanks for getting back with the solution.


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

0 Kudos
MichaelW007
Enthusiast
Enthusiast

No problemo. Thanks for taking a look also. I dug through the properties of the device specs using get-member and just querying the properties till I eventually narrowed down the defective calls. There was a few, such as my capacitykb variable and also the controllerkey and unitnumber. So wasn't just one bug in my code. Got a message back from Alan Renouf on Twitter and the API's are meant to be backwards compatible, so breaking the once working script was unexpected. I also looked through the online documentation and the documentation is correct. In the 5.0 documentation the controller key can be retrieved by doing a $ctrll.key, but that property doesn't exist in 5.5 documentation in the same place anymore, or in 5.5 U1 implementation, it's instead under $ctrll.extensiondata.key. So perhaps this was something that got 'fixed' in 5.5 U1.

0 Kudos