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!
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
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.
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
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.
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
Great, thanks a lot!
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
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!
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
VMware Support came up with a solution.
Big thanks to Jain
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
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
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
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
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
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
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