patrickmc
Contributor
Contributor

Re-register VMs when a datastore got moved?

I recently had a datastore "move" - it had a different signature from the SAN, and so all the VMs on that DS are "inaccessible" but there's another datastore that contains all those files.

I don't feel like going through and re-registering them all by hand. Is there a way to find and register each one automatically?

I've already tried the script elsewhere on the forum, but it doesn't actually work with my tools, and I only need to re-register one DS anyway.

Thanks!

0 Kudos
16 Replies
LucD
Leadership
Leadership

Was this the script you used?

And what errors are you getting ?

Could you tell us what your "tools" are ?


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

0 Kudos
patrickmc
Contributor
Contributor

Yes, that's the script I used. Actually, it isn't throwing errors anymore. But all the VMX files are named far shorter names than the actual VMs are. In the VIC, if I don't enter a name at all, it reads the name from inside the VMX file and uses that. Is there a way to do that from the script?

I tried passing $null instead of $matches[1] for the name, but that gives an error from the server.

0 Kudos
LucD
Leadership
Leadership

Is there any rule/link between the VM name and the name of the VMX file ?

Could you post an example ? (provided your company policy allows this).


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

0 Kudos
patrickmc
Contributor
Contributor

Sometimes yes, sometimes no.

For example, there is a VM named:

NBOAA Arabic Windows XP Professional

and the underlying VMX file:

NBOAA Arabic Windows XP Professi_2/NBOAA Arabic Windows XP Professi.vmx

Sometimes there can be two or three machines with the same VMX filename thanks to this filename length limitation.

0 Kudos
LucD
Leadership
Leadership

Ok, I see.

I'll adapt the script to get the VM name from inside the VMX file.

Hold on.


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

0 Kudos
patrickmc
Contributor
Contributor

Great, thanks a lot!

0 Kudos
LucD
Leadership
Leadership

After a first look I thought the script didn't have to change much.

In the SDK Reference for the RegisterVM_Taskmethod it says for the name parameter, "If this parameter is not set, the displayName configuration parameter of the virtual machine is used."

But unfortunately that doesn't seem to work.

I have opened a Service Request for this.

I'll update the thread when I receive feedback.


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

patrickmc
Contributor
Contributor

Yes, that was my impression too (and it works from the VIC, so their API should work for us too)

Instead, I modified the community extensions to provide this service. It's not perfect (sometimes I got 404s from the VC server when getting a VMX, for example) but it does do a better job than before. I also fixed a bug with the get-vmxformatdata function - it was only returning key/value pairs that didn't have spaces in the value.

I don't really want to jump through the hoops to make a Codeplex patch, so I've attached a standard .patch file that includes my changes here, since I notice you're one of the devs on that project.

Hopefully this contribution helps.

Thanks!

0 Kudos
LucD
Leadership
Leadership

Thanks Patrick.

I'll try to inject the patch but I have to admit that is new territory for me as well.

Fyi, VMware is working on my Service Request.

I'll let you know if that brings a solution.


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

0 Kudos
LucD
Leadership
Leadership

VMware Support came up with a solution.

Big thanks to Jain Smiley Happy

The problem was basically how to "not set" the name parameter from within PowerShell.

This is a version of the script that forces VI to use the DisplayName when registering a .vmx file.

$folder = Get-View (Get-Datacenter -Name <datacenter> | Get-Folder -Name "vm").ID
$pool = Get-View (Get-Cluster -Name <cluster> | Get-ResourcePool -Name "Resources").ID

$esxImpl = Get-VMHost -Name <ESX-host>
$esx = Get-View $esxImpl.ID 
$dsBrowser = Get-View $esx.DatastoreBrowser
foreach($dsImpl in $dsBrowser.Datastore){
	$ds = Get-View $dsImpl
	$vms = @()
	foreach($vmImpl in $ds.Vm){
		$vm = Get-View $vmImpl
		$vms += $vm.Config.Files.VmPathName
	}
	$datastorepath = ""

	$searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
	$searchSpec.matchpattern = "*.vmx"

	$taskMoRef = $dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec) 
	$task = Get-View $taskMoRef 
	while ($task.Info.State -eq "running"){$task = Get-View $taskMoRef}

	foreach ($file in $task.info.Result){
		$found = $FALSE
		foreach($vmx in $vms){
			if(($file.FolderPath + $file.File[0].Path) -eq $vmx){
				$found = $TRUE
			}
		}
		if (-not $found -and $task.Info.Result[0].File -ne $null){
			$vmx = $file.FolderPath + $file.File[0].Path
			$params = @($vmx,$null,$FALSE,$pool.MoRef,$null)
			$folder.GetType().GetMethod("RegisterVM_Task").Invoke($folder, $params)

		}
	}
}


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

0 Kudos
gurjitd
Contributor
Contributor

Hi,

I have one question, can we make this script to just provide the list of the VM's which are not registered ?

Thanks in advance.

Gurjit Dhillon

0 Kudos
LucD
Leadership
Leadership

Yes, that should be quite easy.

Replace the call to the RegisterVM_Task method by a Write-Host for example.

When I'm back to my station I can show you the lines if you want.


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

0 Kudos
gurjitd
Contributor
Contributor

Hi Luc,

thanks for your quick responce, yes please provide me the code. I will really help me.

I am also looking for one more code, where I can need get the list of all the vm along with the datastore which dosen't have vmx file, vm has only disk file. if you can help me for this too.

Your help greately appreciated

Gurjit Dhillon

0 Kudos
LucD
Leadership
Leadership

Gurjit,

For listing, on the console, the VXM file of the unregistered guests you just have to replace one line in the last code block.

I commented out the original line.

....
		if (-not $found -and $task.Info.Result[0].File -ne $null){
			$vmx = $file.FolderPath + $file.File[0].Path
			$params = @($vmx,$null,$FALSE,$pool.MoRef,$null)
#			$folder.GetType().GetMethod("RegisterVM_Task").Invoke($folder, $params)
			Write-Host "Unregistered VM - VMX file" $vmx

		}
	}
}

If I understood your 2nd question correctly, you want to list all the guests that have disk files (.vmdk) on datastore different from the datastore where the .vmx is stored.

The following script should produce such a list

$report = @()
$vms = Get-View -ViewType VirtualMachine
foreach($vm in $vms){
	foreach($dev in $vm.Config.Hardware.Device){
		$homePath = $vm.Config.Files.VmPathName.Split("/")[0]
		if($dev.DeviceInfo.Label -like "Hard Disk*"){
			if($dev.Backing.FileName.Split("/")[0] -ne $homePath){
				$row = "" | Select Name, Home, Datastore
				$row.Name = $vm.Name
				$row.Home = $homePath
				$row.Datastore = $dev.Backing.FileName
				$report += $row
			}
		}
	}
}
$report | Export-Csv "C:\HD-report.csv" -noTypeInformation


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

0 Kudos
gurjitd
Contributor
Contributor

Hi,

Thanks for your script, I will be trying it today.

for the secound quesuion, I want to search the vmdk file which doesnt have its vmx configuration file. In our environment I have seen there are few vmdk, for which I cannot find its confiiguration file on any datastor, dont no why , may be not deleted the VM properly.

I belive above point will help you to understand my view.

Regards

Gurjit Dhillon

0 Kudos
LucD
Leadership
Leadership

Ok, I think I got it. You want to list all .VMDK files that are not referenced in any .VMX file.

So-called orphaned .VMDK files.

That is a completely different script, let me think about it first.

I'll get back to you.


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

0 Kudos