Update: I’ve since found out that mattboren actually found out about this before me and posted something on the VMware communities which I missed. Well found Matt.
A fairly common request is to be able to register existing VMs in a datastore in the vCenter inventory.
This can be a life saver if you have had storage issues and have had to present a backup copy of a datastore which has a different name and need to add the VMs to the inventory, a very laborious process if done manually with right-click Add to Inventory.
This can also be useful in a business recovery process when you need to add VMs that have been mirrored by storage replication over to a secondary site and you need to add them into your inventory.
PowerCLI guru, Luc Dekens has developed a fantastic script called Raiders of the Lost VMX which searches a datastore for .VMX files, and adds them to the vCenter inventory. This script has been updated over the years with even more clever functionality.
Adding the VM to the inventory involved running the RegisterVM_Task Method against the VM Folder in VC.
By accident I discovered there’s actually an updated easier way to add existing VMs to the inventory if you have the .VMX file path. I’m not sure when this was added to PowerCLI but I found it when writing a script to add a new VM.
The New-VM cmdlet now has a new parameter -VMFilePath which allows you to specify a path to the virtual machine you want to register.
This is in the format: [mydatastore] SERVER01/SERVER01.vmx
You can therefore use New-VM to add an existing VM to the VC inventory without having to invoke any MoRef!
In its simplest form:
$VMXFile = "\[mydatastore\] SERVER01/SERVER01.vmx" $ESXHost = "VMHost01.local New-VM -VMFilePath $VMXFile -VMHost $ESXHost
You can also use the rest of the New-VM parameters to specify a VM Folder Location and a Resource Pool.
$VMXFile = "\[mydatastore\] SERVER01/SERVER01.vmx" $ESXHost = "VMHost01.local" $VMFolder = Get-Folder "Prod Servers" $ResPool = "Servers\_Prod1" New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -ResourcePool $ResPool
Even in a single line:
New-VM -VMFilePath "\[mydatastore\] SERVER01/SERVER01.vmx" -VMHost "VMHost01.local" -Location (Get-Folder "Prod Servers" -ResourcePool "Servers\_Prod1"
You can combine this with a simple yet powerful search to go through a set of datastores, find the .VMX files and add them to your Inventory
If you are using NFS and can see Snapshot folders when browsing the inventory you want to exclude these from the search results as they are storage snapshot copies of your VMs, a task easily done in PowerCLI.
$Cluster = "LON\_PROD1" $Datastores = "lonservers\*" $VMFolder = "LondonAppServers" $ESXHost = Get-Cluster $Cluster | Get-VMHost | select -First 1
foreach($Datastore in Get-Datastore $Datastores) { # Set up Search for .VMX Files in Datastore $ds = Get-Datastore -Name $Datastore | %{Get-View $\_.Id} $SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec $SearchSpec.matchpattern = "\*.vmx" $dsBrowser = Get-View $ds.browser $DatastorePath = "\[" + $ds.Summary.Name + "\]"
\# Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS) $SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$\_.FolderPath -notmatch ".snapshot"} | %{$\_.FolderPath + ($\_.File | select Path).Path}
#Register all .vmx Files as VMs on the datastore foreach($VMXFile in $SearchResult) { New-VM -VMFilePath $VMXFile -VMHost $ESXHost -Location $VMFolder -RunAsync } }