Add all Virtual Machines in a DataStore to vCenter Inventory

here are situations when you have VMs on disk, but vCenter does not know about them – i.e. they are not in the inventory. While it is fairly easy to add a single machine to the inventory, doing so for dozens or hundreds or VMs is too tedious to do manually. This script automates the process.

#
# Traverses all folders of a data store and adds all VMX files to the inventory
#
# Example:
#
# .\Add-VMXToInventory.ps1 -DatastoreName My_Datastore -VMFolder VDI -vCenter vcentername -ESXHost host.domain.com
#
 
param
(
   [Parameter(Mandatory=$true)] [string] $DatastoreName,		# Case sensitive
   [Parameter(Mandatory=$true)] [string] $VMFolder,			
   [Parameter(Mandatory=$true)] [string] $vCenter,
   [Parameter(Mandatory=$true)] [string] $ESXHost
)
 
#
# General options
#
#Requires -Version 2 
 
Set-StrictMode -Version 2
 
#
# Functions
#
# Loads snapins
function LoadSnapins([string[]] $snapins)
{
   $loaded = Get-PSSnapin -Name $snapins -ErrorAction SilentlyContinue | % {$_.Name}
   $registered = Get-pssnapin -Name $snapins -Registered -ErrorAction SilentlyContinue  | % {$_.Name}
   $notLoaded = $registered | ? {$loaded -notcontains $_}
 
   if ($notLoaded -ne $null)
   {
      foreach ($newlyLoaded in $notLoaded)
	  {
         Add-PSSnapin $newlyLoaded
      }
   }
}
 
 
#
# Start of script
#
# Load snapins
LoadSnapins @("VMware.VimAutomation.Core")
 
# Avoid stupid questions
Set-PowerCLIConfiguration -DefaultVIServerMode multiple -Confirm:$false
 
# Connect to vCenter
Connect-VIServer $vCenter
 
# Set up search for .VMX files in datastore
$ds = Get-Datastore -Name $DatastoreName | %{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
}