erickmiller
Enthusiast
Enthusiast

Adding an existing hard disk

Jump to solution

Hi,

Is there a way to use the toolkit to add an existing hard disk file to an existing virtual machine? On the opposite end, is there a way to remove a hard disk from a powered-down VM with either deleting or not-deleting the disk files using the toolkit?

Thanks!

Eric K. Miller, Genesis Hosting Solutions, LLC

- Lease part of our ESX cluster!

Eric K. Miller, Genesis Hosting Solutions, LLC http://www.genesishosting.com/ - Lease part of our ESX cluster!
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

From our VI Toolkit snippet-vault.

The following 2 functions do probably most of what you want.

Function add-HD uses an existing .vmdk file to create a hard disk on a VM.

The calling syntax: add-HD <VM-name> <datastore-name> <path-to-vmdk> <controller-label>

An example: add-HD "PC4" "vmfs2" "PC4/PC4.vmdk" "SCSI Controller 0"

Function remove-HD removes a hard disk from a VM and optionally deletes the .vmdk file.

The calling syntax: remove-HD <VM-name> <hard-disk-label> <delete-flag>

An example: remove-HD "PC4" "Hard Disk 3" $TRUE

The code:

Get-VIServer -Server <VC-server>

[http://Reflection.Assembly|http://Reflection.Assembly]::LoadWithPartialName("vmware.vim")

function remove-HD {
  param($VMname, $HDname, $Delflag)
  
  $vm = Get-View (Get-VM $VMname).ID

  foreach($dev in $vm.Config.Hardware.Device){
    if ($dev.DeviceInfo.Label -eq $HDname){
      $key = $dev.Key
	  $name = $dev.Backing.FileName
    }
  }

  $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $spec.deviceChange = @()
  $spec.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec
  $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDevice
  $spec.deviceChange[0].device.key = $key
  $spec.deviceChange[0].operation = "remove"

  $vm.ReconfigVM_Task($spec)

  if ($Delflag){
    $svcRef = new-object VMware.Vim.ManagedObjectReference
    $svcRef.Type = "ServiceInstance"
    $svcRef.Value = "ServiceInstance"
    $serviceInstance = get-view $svcRef

    $fileMgr = Get-View $serviceInstance.Content.fileManager

    $datacenter = (Get-View (Get-VM $VMname | Get-Datacenter).ID).get_MoRef()
	
    $fileMgr.DeleteDatastoreFile_Task($name, $datacenter)
  }
}

function add-HD {
  param($VMname, $DSname, $Filename, $SCSIcntrl)

  $vm = Get-View (Get-VM $VMname).ID
  $ds = Get-View (Get-Datastore -Name $DSname).ID
  foreach($dev in $vm.config.hardware.device){
    if ($dev.deviceInfo.label -eq $SCSIcntrl){
	  $CntrlKey = $dev.key
	}
  }
  $Unitnumber = 0
  $DevKey = 0
  foreach($dev in $vm.config.hardware.device){
    if ($dev.controllerKey -eq $CntrlKey){
	  if ($dev.Unitnumber -gt $Unitnumber){$Unitnumber = $dev.Unitnumber}
	  if ($dev.key -gt $DevKey) {$DevKey = $dev.key}
	}
  }

  $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $spec.deviceChange = @()
  $spec.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec

  $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDisk
  $spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo
  $spec.deviceChange[0].device.backing.datastore = $ds.MoRef
  $spec.deviceChange[0].device.backing.fileName = "[" + $DSname + "] " + $Filename
  $spec.deviceChange[0].device.backing.diskMode = "independent_persistent"
  $spec.deviceChange[0].device.key = $DevKey + 1
  $spec.deviceChange[0].device.unitnumber = $Unitnumber + 1
  $spec.deviceChange[0].device.controllerKey = $CntrlKey
  $spec.deviceChange[0].operation = "add"

  $vm.ReconfigVM_Task($spec)
}

Since the forum SW apparently has a mind of it's own I have attached the code.

Note that the functions can definitely be improved.

Currently the fail-safe mechanisms are quit limited.

If there is a need to explain parts of the code please let me know.

And of course, use in a production environment at your own risk ! Smiley Wink


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

View solution in original post

0 Kudos
8 Replies
kjb007
Immortal
Immortal

There isn't an easy answer here for you, I'm afraid. The get-harddisk allow you to get a disk object, but it has to exist on a vm, template, or a snapshot. The new-harddisk allows you to create a new disk and add it to a vm, but again, not an existing that I can see. You will have to get deeply involved with views, and I'm sure there are others on this forum who can provide the requisite direction for you. It will depend on how comfortable you are with scripting, to get an involved answer, or were you looking for a quick answer?

-KjB

vExpert/VCP/VCAP vmwise.com / @vmwise -KjB
erickmiller
Enthusiast
Enthusiast

Thanks for your reply! I'm very comfortable with scripting, and if we have to delve deep into the API, I'm willing to do it, hopefully as long as we can do it through the Toolkit. We have some Java routines we wrote a long time ago that talk directly to the API, but the Toolkit is SO much easier that we abandoned that approach.

Basically, what we're trying to do, is pre-mass-produce a number of copies of some hard disk images and attach them to various VMs on-demand.

Eric K. Miller, Genesis Hosting Solutions, LLC

- Lease part of our ESX cluster!

Eric K. Miller, Genesis Hosting Solutions, LLC http://www.genesishosting.com/ - Lease part of our ESX cluster!
0 Kudos
LucD
Leadership
Leadership

From our VI Toolkit snippet-vault.

The following 2 functions do probably most of what you want.

Function add-HD uses an existing .vmdk file to create a hard disk on a VM.

The calling syntax: add-HD <VM-name> <datastore-name> <path-to-vmdk> <controller-label>

An example: add-HD "PC4" "vmfs2" "PC4/PC4.vmdk" "SCSI Controller 0"

Function remove-HD removes a hard disk from a VM and optionally deletes the .vmdk file.

The calling syntax: remove-HD <VM-name> <hard-disk-label> <delete-flag>

An example: remove-HD "PC4" "Hard Disk 3" $TRUE

The code:

Get-VIServer -Server <VC-server>

[http://Reflection.Assembly|http://Reflection.Assembly]::LoadWithPartialName("vmware.vim")

function remove-HD {
  param($VMname, $HDname, $Delflag)
  
  $vm = Get-View (Get-VM $VMname).ID

  foreach($dev in $vm.Config.Hardware.Device){
    if ($dev.DeviceInfo.Label -eq $HDname){
      $key = $dev.Key
	  $name = $dev.Backing.FileName
    }
  }

  $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $spec.deviceChange = @()
  $spec.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec
  $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDevice
  $spec.deviceChange[0].device.key = $key
  $spec.deviceChange[0].operation = "remove"

  $vm.ReconfigVM_Task($spec)

  if ($Delflag){
    $svcRef = new-object VMware.Vim.ManagedObjectReference
    $svcRef.Type = "ServiceInstance"
    $svcRef.Value = "ServiceInstance"
    $serviceInstance = get-view $svcRef

    $fileMgr = Get-View $serviceInstance.Content.fileManager

    $datacenter = (Get-View (Get-VM $VMname | Get-Datacenter).ID).get_MoRef()
	
    $fileMgr.DeleteDatastoreFile_Task($name, $datacenter)
  }
}

function add-HD {
  param($VMname, $DSname, $Filename, $SCSIcntrl)

  $vm = Get-View (Get-VM $VMname).ID
  $ds = Get-View (Get-Datastore -Name $DSname).ID
  foreach($dev in $vm.config.hardware.device){
    if ($dev.deviceInfo.label -eq $SCSIcntrl){
	  $CntrlKey = $dev.key
	}
  }
  $Unitnumber = 0
  $DevKey = 0
  foreach($dev in $vm.config.hardware.device){
    if ($dev.controllerKey -eq $CntrlKey){
	  if ($dev.Unitnumber -gt $Unitnumber){$Unitnumber = $dev.Unitnumber}
	  if ($dev.key -gt $DevKey) {$DevKey = $dev.key}
	}
  }

  $spec = New-Object VMware.Vim.VirtualMachineConfigSpec
  $spec.deviceChange = @()
  $spec.deviceChange += New-Object VMware.Vim.VirtualDeviceConfigSpec

  $spec.deviceChange[0].device = New-Object VMware.Vim.VirtualDisk
  $spec.deviceChange[0].device.backing = New-Object VMware.Vim.VirtualDiskFlatVer2BackingInfo
  $spec.deviceChange[0].device.backing.datastore = $ds.MoRef
  $spec.deviceChange[0].device.backing.fileName = "[" + $DSname + "] " + $Filename
  $spec.deviceChange[0].device.backing.diskMode = "independent_persistent"
  $spec.deviceChange[0].device.key = $DevKey + 1
  $spec.deviceChange[0].device.unitnumber = $Unitnumber + 1
  $spec.deviceChange[0].device.controllerKey = $CntrlKey
  $spec.deviceChange[0].operation = "add"

  $vm.ReconfigVM_Task($spec)
}

Since the forum SW apparently has a mind of it's own I have attached the code.

Note that the functions can definitely be improved.

Currently the fail-safe mechanisms are quit limited.

If there is a need to explain parts of the code please let me know.

And of course, use in a production environment at your own risk ! Smiley Wink


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

View solution in original post

0 Kudos
erickmiller
Enthusiast
Enthusiast

This is fantastic! I'll start working with it and see if it does everything we need. I really appreciate your help!

Eric K. Miller, Genesis Hosting Solutions, LLC

- Lease part of our ESX cluster!

Eric K. Miller, Genesis Hosting Solutions, LLC http://www.genesishosting.com/ - Lease part of our ESX cluster!
0 Kudos
halr9000
Commander
Commander

If I'm not mistaken, the [http://Reflection.Assembly|http://Reflection.Assembly]::LoadWithPartialName("vmware.vim") bit is no longer necessary.

Author of the upcoming book: Managing VMware Infrastructure with PowerShell

Co-Host, PowerScripting Podcast (http://powerscripting.net)

My signature used to be pretty, but then the forum software broked it. vExpert. Microsoft MVP (Windows PowerShell). Author, Podcaster, Speaker. I'm @halr9000
0 Kudos
olan025
Enthusiast
Enthusiast

Hey LucD or others...

I am looking to get the remove-HD function working with physicalmode RDMs.

It will remove the .vmdk file, but leaves the rdmp.vmdk file, then error out.

I can attach screen shot tomorrow when I'm back in the office.

Hopefully someone here might know the answer on that... I will start looking around the Views to see if there's anything I can see.

Ryan

_____________________ Created NEW THREAD __________________

http://communities.vmware.com//thread/198055?tstart=0

0 Kudos
Marcel00M
Contributor
Contributor

Hmmm the remove-HD function leave the -flat.vmkd, which is the one that uses the most storage.

ESX and VC Version is 4.0

before:

total 7926508
-rw------- 1 root root  4294967808 Nov 17 11:19 ersatz01_1-flat.vmdk
-rw------- 1 root root         528 Nov 17 11:16 ersatz01_1.vmdk
-rw------- 1 root root 16106127360 Nov 17 11:19 ersatz01_2-flat.vmdk
-rw------- 1 root root         530 Nov 17 11:16 ersatz01_2.vmdk

-rw------- 1 root root 12884901888 Nov 17 11:22 ersatz01-flat.vmdk
-rw------- 1 root root        8684 Nov 17 11:22 ersatz01.nvram
-rw------- 1 root root         528 Nov 17 11:16 ersatz01.vmdk
-rw------- 1 root root           0 Nov 17 11:15 ersatz01.vmsd
-rwxr-xr-x 1 root root        2641 Nov 17 11:22 ersatz01.vmx
-rw------- 1 root root         263 Nov 17 11:22 ersatz01.vmxf
-rw-r--r-- 1 root root       98363 Nov 17 11:10 vmware-168.log
-rw-r--r-- 1 root root      113461 Nov 17 11:10 vmware-169.log
-rw-r--r-- 1 root root       91517 Nov 17 11:10 vmware-170.log
-rw-r--r-- 1 root root       91240 Nov 17 11:10 vmware-171.log
-rw-r--r-- 1 root root       91037 Nov 17 11:10 vmware-172.log
-rw-r--r-- 1 root root       90557 Nov 17 11:10 vmware-173.log
-rw-r--r-- 1 root root       86224 Nov 17 11:22 vmware.log

after:

-rw------- 1 root root  4294967808 Nov 17 11:19 ersatz01_1-flat.vmdk
-rw------- 1 root root         528 Nov 17 11:16 ersatz01_1.vmdk
-rw------- 1 root root 16106127360 Nov 17 11:19 ersatz01_2-flat.vmdk
-rw------- 1 root root 12884901888 Nov 17 11:22 ersatz01-flat.vmdk
-rw------- 1 root root        8684 Nov 17 11:22 ersatz01.nvram
-rw------- 1 root root         528 Nov 17 11:16 ersatz01.vmdk
-rw------- 1 root root           0 Nov 17 11:15 ersatz01.vmsd
-rwxr-xr-x 1 root root        2551 Mar  8 13:35 ersatz01.vmx
-rw------- 1 root root         263 Mar  8 13:35 ersatz01.vmxf
-rw-r--r-- 1 root root       98363 Nov 17 11:10 vmware-168.log
-rw-r--r-- 1 root root      113461 Nov 17 11:10 vmware-169.log
-rw-r--r-- 1 root root       91517 Nov 17 11:10 vmware-170.log
-rw-r--r-- 1 root root       91240 Nov 17 11:10 vmware-171.log
-rw-r--r-- 1 root root       91037 Nov 17 11:10 vmware-172.log
-rw-r--r-- 1 root root       90557 Nov 17 11:10 vmware-173.log
-rw-r--r-- 1 root root       86224 Nov 17 11:22 vmware.log

0 Kudos
Marcel00M
Contributor
Contributor

Ahhh I should use my eyes

You already posted th solution Smiley Wink:

http://communities.vmware.com/message/1281621#1281621

-rw------- 1 root root  4294967808 Nov 17 13:17 ersatz02_1-flat.vmdk
-rw------- 1 root root         528 Nov 17 11:23 ersatz02_1.vmdk
-rw------- 1 root root 16106127360 Nov 17 13:17 ersatz02_2-flat.vmdk
-rw------- 1 root root         530 Nov 17 11:23 ersatz02_2.vmdk
-rw------- 1 root root 12884901888 Nov 17 13:17 ersatz02-flat.vmdk

-rw------- 1 root root        8684 Nov 17 13:18 ersatz02.nvram
-rw------- 1 root root         528 Nov 17 11:22 ersatz02.vmdk
-rw------- 1 root root           0 Nov 17 11:22 ersatz02.vmsd
-rwxr-xr-x 1 root root        2641 Nov 17 13:18 ersatz02.vmx
-rw------- 1 root root         263 Nov 17 13:18 ersatz02.vmxf
-rw-r--r-- 1 root root       98363 Nov 17 11:16 vmware-168.log
-rw-r--r-- 1 root root      113461 Nov 17 11:16 vmware-169.log
-rw-r--r-- 1 root root       91517 Nov 17 11:16 vmware-170.log
-rw-r--r-- 1 root root       91240 Nov 17 11:16 vmware-171.log
-rw-r--r-- 1 root root       91037 Nov 17 11:16 vmware-172.log
-rw-r--r-- 1 root root       90557 Nov 17 11:16 vmware-173.log
-rw-r--r-- 1 root root       87101 Nov 17 13:18 vmware.log

-rw------- 1 root root  4294967808 Nov 17 13:17 ersatz02_1-flat.vmdk
-rw------- 1 root root         528 Nov 17 11:23 ersatz02_1.vmdk
-rw------- 1 root root 12884901888 Nov 17 13:17 ersatz02-flat.vmdk
-rw------- 1 root root        8684 Nov 17 13:18 ersatz02.nvram
-rw------- 1 root root         528 Nov 17 11:22 ersatz02.vmdk
-rw------- 1 root root           0 Nov 17 11:22 ersatz02.vmsd
-rwxr-xr-x 1 root root        2551 Mar  8 16:55 ersatz02.vmx
-rw------- 1 root root         263 Mar  8 16:55 ersatz02.vmxf
-rw-r--r-- 1 root root       98363 Nov 17 11:16 vmware-168.log
-rw-r--r-- 1 root root      113461 Nov 17 11:16 vmware-169.log
-rw-r--r-- 1 root root       91517 Nov 17 11:16 vmware-170.log
-rw-r--r-- 1 root root       91240 Nov 17 11:16 vmware-171.log
-rw-r--r-- 1 root root       91037 Nov 17 11:16 vmware-172.log
-rw-r--r-- 1 root root       90557 Nov 17 11:16 vmware-173.log
-rw-r--r-- 1 root root       87101 Nov 17 13:18 vmware.log

0 Kudos