VMware Cloud Community
Eray_Ekici
Contributor
Contributor

remove harddisk

Is there an updated remove-hd function.

Current one posted on the forum leaves the -flat.vmdk files behind.

Is there a different method than this?

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

Reply
0 Kudos
18 Replies
Eray_Ekici
Contributor
Contributor

I added another delete call, does anyone see issues?

$datacenter = (Get-View (Get-VM $VMname | Get-Datacenter).ID).get_MoRef()

$flatname = $name.substring(0,$name.length - 5) + "-flat.vmdk"

$fileMgr.DeleteDatastoreFile_Task($name, $datacenter)

$fileMgr.DeleteDatastoreFile_Task($flatname, $datacenter)

Reply
0 Kudos
LucD
Leadership
Leadership

No issues.

I took the opportunity to review the entire function.

It can now handle flat disks and raw disks.

function remove-HD {
	param($VMname, $HDname, $Delflag)

	$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"=$VMname}

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

	$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){
		$serviceInstance = get-view ServiceInstance

		$fileMgr = Get-View $serviceInstance.Content.fileManager
		$datacenter = (Get-View (Get-VM $VMname | Get-Datacenter).ID).get_MoRef()

		$fileMgr.DeleteDatastoreFile_Task($name, $datacenter)
		switch($disktype){
			"VirtualDiskRawDiskMappingVer1BackingInfo" {
				$ext = "-rdmp.vmdk"
			}
			"VirtualDiskFlatVer2BackingInfo" {
				$ext = "-flat.vmdk"
			}
		}
		$name2 = $name.substring(0,$name.length - 5) + $ext
		$fileMgr.DeleteDatastoreFile_Task($name2, $datacenter) 
	}
}

remove-HD "MyVM" "Hard Disk 3" $true
remove-HD "MyVM" "Hard Disk 2" $true

Note that the order in which you remove hard disks is important.

Suppose you have 3 hard disks and if you remove "Hard Disk 2" the old "Hard Disk 3" will be renamed to "Hard Disk 2".


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

Reply
0 Kudos
milson
Enthusiast
Enthusiast

This works great in single-VI-endpoint mode, thanks! I've noticed however a couple of issues when connected to more than one vCenter with newer PowerCLI versions (which is the default behavior), specifically around removing the HDD files when $true is specified:

1) ServiceInstance becomes an array in this mode, so $serviceInstance.Content.fileManager fails (which trips up the function later - I thought I could fix this with a simple foreach loop - but due to #2, I think, the function still fails)

2) For some strange, reason, when populating $datacenter '.get_MoRef()' stops being a valid method, seemingly only when more than one VI connection exists. I'm no VI API expert, but that seems quite odd to me (and it trips up later portions of the function as well, which have no valid object to operate on)

Initially, I just created a simple 'foreach' loop to handle the ServiceInstance array as separate objects, but due to the .get_MoRef() complication, that doesn't work (and my powershell/powerCLI scripting skills are starting to hit the wall much beyond this...)

Here's hoping that the core PowerCLI Remove-HardDisk cmdlet gets a simple 'delete backing files' option soon Smiley Happy

Regards,

Milson

Reply
0 Kudos
LucD
Leadership
Leadership

Yes, you right.

If you run PowerCLI in "multiple" server mode the Remove-HD function doesn't work.

This is the updated version.

You can now add a -Server parameter.

If you don't specify a -Server parameter the function execute against the $defaultVIServer.

function remove-HD {
	param($VMname, $HDname, $Delflag, $Server)

	if(!$Server){
		$server = $defaultVIServer
	}
	
	$vm = Get-View -Server $server -ViewType VirtualMachine -Filter @{"Name"=$VMname}

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

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

	if ($Delflag){
		$serviceInstance = get-view ServiceInstance -Server $Server

		$fileMgr = Get-View $serviceInstance.Content.fileManager
		$datacenter = (Get-View (Get-VM $VMname -Server $Server | Get-Datacenter).ID).get_MoRef()

		$fileMgr.DeleteDatastoreFile_Task($name, $datacenter)
		switch($disktype){
			"VirtualDiskRawDiskMappingVer1BackingInfo" {
				$ext = "-rdmp.vmdk"
			}
			"VirtualDiskFlatVer2BackingInfo" {
				$ext = "-flat.vmdk"
			}
		}
		$name2 = $name.substring(0,$name.length - 5) + $ext
		$fileMgr.DeleteDatastoreFile($name2, $datacenter) 
	}
}

remove-HD "MyPC" "Hard Disk 2" $true $defaultVIServers[1]

____________

Blog: LucD notes

Twitter: lucd22


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

Reply
0 Kudos
milson
Enthusiast
Enthusiast

FYI - I recently had a chance to get this missing cmdlet functionality in front of a PM at VMware, and lo - the parameter has arrived in 4.1 u1!

"Improvement - Added the DeletePermanentlyparameter to Remove-HardDisk for deleting hard disk files from the datastore."

Regards,

Milson

Reply
0 Kudos
Marcel00M
Contributor
Contributor

I have some VM´s that work and some not

For the "bad" VM´s the Error is:

Method invocation failed because [System.Object[]] doesn't contain a method named 'ReconfigVM_Task'.
At C:\Programme\VMware\Infrastructure\vSphere PowerCLI\Scripts\grow_d_delete_f_new_f.ps1:21 char:25
+      $vm.ReconfigVM_Task <<<< ($spec)
    + CategoryInfo          : InvalidOperation: (ReconfigVM_Task:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound

I run all the VM´s in the same environment ESX 4.0/VC4.0. So I can not use the remove-harddisk cmdlet with the parameter DeletePermanently

What can I do to fix?

Please help me

Reply
0 Kudos
avlieshout
VMware Employee
VMware Employee

Looks like you're trying to invoke the reconfigvm_task method on an array instead of a vm object.

Arnim van Lieshout Blogging: http://www.van-lieshout.com Twitter: http://www.twitter.com/avlieshout If you find this information useful, please award points for "correct" or "helpful".
Reply
0 Kudos
Marcel00M
Contributor
Contributor

Hmm Sorry I am not a good coder... just an poor admin *g*

I run this simple script (Just to test the function, I dont use a while loop etc etc)

script = delete_f_test.ps1

This is the content (exept VMNAME and VCIP):

##################################################

function remove-HD {

     param($VMname, $HDname, $Delflag, $Server)

     if(!$Server){

          $server = $defaultVIServer

     }

     $vm = Get-View -Server $server -ViewType VirtualMachine -Filter @{"Name"=$VMname}

     foreach($dev in $vm.Config.Hardware.Device){

          if ($dev.DeviceInfo.Label -eq $HDname){

               $key = $dev.Key

               $name = $dev.Backing.FileName

               $disktype = $dev.Backing.GetType().Name

          }

     }

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

     if ($Delflag){

          $serviceInstance = get-view ServiceInstance -Server $Server

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

          $datacenter = (Get-View (Get-VM $VMname -Server $Server | Get-Datacenter).ID).get_MoRef()

          $fileMgr.DeleteDatastoreFile_Task($name, $datacenter)

          switch($disktype){

               "VirtualDiskRawDiskMappingVer1BackingInfo" {

                    $ext = "-rdmp.vmdk"

               }

               "VirtualDiskFlatVer2BackingInfo" {

                    $ext = "-flat.vmdk"

               }

          }

          $name2 = $name.substring(0,$name.length - 5) + $ext

          $fileMgr.DeleteDatastoreFile($name2, $datacenter)

     }

}

echo "start"

remove-HD "VNAME" "Hard Disk 3" $TRUE "VCIP"

#########################################################

And that is the error message:

[vSphere PowerCLI] C:\Programme\VMware\Infrastructure\vSphere PowerCLI\Scripts> delete_f_test.ps1
start
Method invocation failed because [System.Object[]] doesn't contain a method named 'ReconfigVM'.
At C:\Programme\VMware\Infrastructure\vSphere PowerCLI\Scripts\delete_f_test.ps1:25 char:20
+      $vm.ReconfigVM <<<< ($spec)
    + CategoryInfo          : InvalidOperation: (ReconfigVM:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound


Type                                                           Value
----                                                           -----
Task                                                           task-12148
You cannot call a method on a null-valued expression.
At C:\Programme\VMware\Infrastructure\vSphere PowerCLI\Scripts\delete_f_test.ps1:42 char:35
+           $name2 = $name.substring <<<< (0,$name.length - 5) + $ext
    + CategoryInfo          : InvalidOperation: (substring:String) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Exception calling "DeleteDatastoreFile" with "2" argument(s): "Invalid datastore path ''."
At C:\Programme\VMware\Infrastructure\vSphere PowerCLI\Scripts\delete_f_test.ps1:43 char:39
+           $fileMgr.DeleteDatastoreFile <<<< ($name2, $datacenter)
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

[vSphere PowerCLI] C:\Programme\VMware\Infrastructure\vSphere PowerCLI\Scripts>

Can I use a Folder instead (like get-folder disk_change | get-vm) what will be the synthax then?

Reply
0 Kudos
avlieshout
VMware Employee
VMware Employee

You have multiple vms with the same name or multiple connections.

Try get-vm vmname and see if multiple objects are returned.

Arnim van Lieshout Blogging: http://www.van-lieshout.com Twitter: http://www.twitter.com/avlieshout If you find this information useful, please award points for "correct" or "helpful".
Reply
0 Kudos
Marcel00M
Contributor
Contributor

The name of the testvm is unique.

Just to understand:  It is not relevant, when there are other multiple vm´s. Or is it relevant for my test with this single VM?

What do You mean with multiple connections. Do You mean the VC Server. Well I work in a larger Team and I can not kick everbody, when I´ll want to run a script ? But the function works for one vm and not for the other, there where only seconds between (in the earlier test I tried an while loop with 10 vm´s)

I Just want to delete the disk for many VM´s . I must use a loop ore somthing. Can I use a folder object (get-folder | get-vm) instead a VM name to make shure that I´ll use a object instead of an hash?

(I´ll cloned the VM´s etc with bash scripts and vmkfstools on the linux service console, thats my home. This "object based and powershell thing" is new for me, sorry for maybe asking stupid question :smileyblush: Smiley Wink)

Reply
0 Kudos
avlieshout
VMware Employee
VMware Employee

What does Get-VM "uniquename" return?

From the error message it looks like more than one VM is returned.

This can happen when you are connected multiple times to the same server.

Arnim van Lieshout Blogging: http://www.van-lieshout.com Twitter: http://www.twitter.com/avlieshout If you find this information useful, please award points for "correct" or "helpful".
Reply
0 Kudos
Marcel00M
Contributor
Contributor

OK sorry I dident wrote this clear yersterday. As I wrote that the VN Name is unique, I meant that I typet get-vm > test.txt and searched test.txt with an editor for similar or exact name(es). There is only one.

What to You mean with Server. ESX Server or VC Server?

Reply
0 Kudos
LucD
Leadership
Leadership

I think Arnim is right, can you do

$defaultVIServers

at the PowerCLI prompt.

I suspect that it will show more than 1 entry.


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

Reply
0 Kudos
Marcel00M
Contributor
Contributor

No (I´ll tryed thi systerday


[vSphere PowerCLI] C:\Programme\VMware\Infrastructure\vSphere PowerCLI> echo $defaultVIServers

Name                                      Port
----                                      ----
10.229.191.145                            443


@LucD is there a way to use Your function with an get-folder object, to avoid buggy input?
Reply
0 Kudos
Marcel00M
Contributor
Contributor

Another Question independent from multiple connections etc.

I have some VM´s that make no problems and som that do.

Would that not exclude connection issue´s ?

I try to focus on the difference between the good and the bad VM´s

But I could not figure out, whats the difference between the good and the bad VM´s.

I also get an Message in VC "ungültiger Dateipfad" which means the path to the vmdk is not correct.

I thing thats the rigth way to search. Something with the data store must be the problem.

But When I use get-vm VMNAME | Get-HardDisk | select * PowerCLI shows all 3 disks with the names I use in the function:

StorageFormat   : Thin
Persistence     : Persistent
DiskType        : Flat
Filename        : [VM_pT_114] QDEAJY/QDEAJY_c.vmdk
CapacityKB      : 12582912
ParentId        : VirtualMachine-vm-646
ConnectionState :
Id              : VirtualMachine-vm-646/2000
Name            : Hard disk 1

StorageFormat   : Thin
Persistence     : Persistent
DiskType        : Flat
Filename        : [VM_pT_114] QDEAJY/QDEAJY_d.vmdk
CapacityKB      : 4194304
ParentId        : VirtualMachine-vm-646
ConnectionState :
Id              : VirtualMachine-vm-646/2001
Name            : Hard disk 2

StorageFormat   : Thin
Persistence     : Persistent
DiskType        : Flat
Filename        : [VM_pT_114] QDEAJY/QDEAJY_f.vmdk
CapacityKB      : 15728640
ParentId        : VirtualMachine-vm-646
ConnectionState :
Id              : VirtualMachine-vm-646/2002
Name            : Hard disk 3

Any ideas?

Reply
0 Kudos
Marcel00M
Contributor
Contributor

I found some .snapshot directorys on the storage. I dont now what the do (The admin of the esx is atnother person. I am the admin of the VM´s with right ins the esx and vc. I can not reach him) and whether this the reason. But there are snapshots for the "bad"  VM´s, but not for the "good" VM´s

Is this a good trace to go in deeper analysis?

Reply
0 Kudos
Marcel00M
Contributor
Contributor

There where some old snapshots on the filer from the storage team. But removing them and try again was not successfully. Think I will remove the disks from the vm config and delete them with a shell script under the service console.

Reply
0 Kudos
Marcel00M
Contributor
Contributor

Looks like the VM is unique:

[vSphere PowerCLI] C:\> echo $defaultVIServer

Name                                      Port
----                                      ----
10.229.191.145                            443


[vSphere PowerCLI] C:\> get-vm QDEAHX

Name                 PowerState Num CPUs Memory (MB)
----                 ---------- -------- -----------
QDEAHX               PoweredOff 1        900

But When I add an echo $vm lines in the function. I get two Outputs =

MoRef : VirtualMachine-vm-498 and VirtualMachine-vm-14888

Is this the Problem? What can I do to fix?


Capability           : VMware.Vim.VirtualMachineCapability
Config               : VMware.Vim.VirtualMachineConfigInfo
Layout               : VMware.Vim.VirtualMachineFileLayout
LayoutEx             : VMware.Vim.VirtualMachineFileLayoutEx
Storage              : VMware.Vim.VirtualMachineStorageInfo
EnvironmentBrowser   :
ResourcePool         :
ResourceConfig       : VMware.Vim.ResourceConfigSpec
Runtime              : VMware.Vim.VirtualMachineRuntimeInfo
Guest                : VMware.Vim.GuestInfo
Summary              : VMware.Vim.VirtualMachineSummary
Datastore            : {Datastore-datastore-51}
Network              : {Network-network-68}
Snapshot             :
GuestHeartbeatStatus : gray
Parent               : Folder-group-v14914
CustomValue          : {}
OverallStatus        : green
ConfigStatus         : green
ConfigIssue          : {}
EffectiveRole        : {-1}
Permission           : {}
Name                 : QDEAHX
DisabledMethod       : {MakePrimaryVM_Task, TerminateFaultTolerantVM_Task, ReconfigVM_Task, RelocateVM_Task...}
RecentTask           : {}
DeclaredAlarmState   : {alarm-11.vm-14888, alarm-12.vm-14888, alarm-2.vm-14888, alarm-24.vm-14888...}
TriggeredAlarmState  : {}
AlarmActionsEnabled  : True
Tag                  : {}
Value                : {}
AvailableField       : {}
MoRef                : VirtualMachine-vm-14888
Client               : VMware.Vim.VimClient

Capability           : VMware.Vim.VirtualMachineCapability
Config               : VMware.Vim.VirtualMachineConfigInfo
Layout               : VMware.Vim.VirtualMachineFileLayout
LayoutEx             : VMware.Vim.VirtualMachineFileLayoutEx
Storage              : VMware.Vim.VirtualMachineStorageInfo
EnvironmentBrowser   : EnvironmentBrowser-envbrowser-498
ResourcePool         : ResourcePool-resgroup-193
ResourceConfig       : VMware.Vim.ResourceConfigSpec
Runtime              : VMware.Vim.VirtualMachineRuntimeInfo
Guest                : VMware.Vim.GuestInfo
Summary              : VMware.Vim.VirtualMachineSummary
Datastore            : {Datastore-datastore-17}
Network              : {Network-network-68}
Snapshot             :
GuestHeartbeatStatus : gray
Parent               : Folder-group-v14857
CustomValue          : {}
OverallStatus        : green
ConfigStatus         : green
ConfigIssue          : {}
EffectiveRole        : {-1}
Permission           : {}
Name                 : QDEAHX
DisabledMethod       : {MakePrimaryVM_Task, TerminateFaultTolerantVM_Task, RevertToCurrentSnapshot_Task, RemoveAllSnapshots_
                       Task...}
RecentTask           : {}
DeclaredAlarmState   : {alarm-11.vm-498, alarm-12.vm-498, alarm-2.vm-498, alarm-24.vm-498...}
TriggeredAlarmState  : {}
AlarmActionsEnabled  : True
Tag                  : {}
Value                : {}
AvailableField       : {}
MoRef                : VirtualMachine-vm-498
Client               : VMware.Vim.VimClient

Reply
0 Kudos