Find orphaned.vmx files (VMware Powershell)

Needs to be to edited for your environments and vcenter server names.  This was written for an ESX 3.5 environment and I have not run it against vSphere.  Some code liberated from the scripting communities at

#Script to report on orphan .vmx files
#Written by Josh Andrews 7/20/09
#Script assumes VIToolkit/PowerCLI environment
#Script assumes all hosts are in clusters
#Script assumes first host found in cluster will have access to all datastores
#Assumes if a cluster has one datastore that has already been searched then all
# its datastores have been searched
#Users running script needs adequate permissions to search

#dots function prints “.” accross the screen to give some feedback to user.
function dots {write-host “.” -nonewline}

## Load VI components and set the environment
$run = “C:WindowsPowerShellMicrosoft.PowerShell_profile.ps1”

### Let the user choose the environment
Write-output “_____________________________________________”
Write-output ” Find Orphan .VMX v1 ”
Write-output “_____________________________________________”
Write-output “Orphan list saved to “C:Unregistered-VMX.csv”
Write-output ” ”
Write-output “Choose the environment to check”
Write-output ” 1. Production”
Write-output ” 2. Disaster Recovery”
Write-output ” 3. Lab”
Write-output ” 4. Test”
Write-output ” ”

$WhichEnv = Read-Host “=>”
while ( -not (‘1234’ -match $WhichEnv))
{$WhichEnv = Read-Host “=>”
Write-output ” ”

switch ($WhichEnv)
1 {$WhichEnv = “ProductionServer”}
2 {$WhichEnv = “DisasterRecoveryServer”}
3 {$WhichEnv = “LabServer”}
4 {$WhichEnv = “TestServer”}

### Connect to the Virtual Center Server for the choosen environment
$VC = connect-viserver -server $WhichEnv
while ( -not $VC)
$VC = connect-viserver -server $WhichEnv

#set variables
$report = @()
$Datastorelist = “”

# get all datacenters known to the vcenter server and perform rest of script on one datacenter at a time
Get-Datacenter | % {
$datacenter = $_
# get all clusters on the datacenter and perform rest of script on one cluster at a time
$_ | Get-Cluster | % {
$cluster = $_

# get the first host in the cluster
$esxImpl = Get-Cluster -Name $cluster | Get-VMHost | select -First 1

#Make sure the cluster has at least one host
if($esxImpl -ne $null){
$esx = Get-View $esxImpl.ID
$dsBrowser = Get-View $esx.DatastoreBrowser

#loop for each datastore found
foreach($dsImpl in $dsBrowser.Datastore){
$ds = Get-View $dsImpl
$vms = @()

#if the datastore has been checked before, break out
#note that this assumes all clusters have either the
#same datastores or entirely different data stores
if ($datastorelist -match $ds.Summary.Name) {break}
$datastorelist += $ds.Summary.Name

# add the VMX paths for all VMs found into variable “vms”
foreach($vmImpl in $ds.Vm){
$vm = Get-View $vmImpl
$vms += $vm.Config.Files.VmPathName

# build a datastore search for all .vmx files and execute.
$datastorepath = “[” + $ds.Summary.Name + “]”
$searchspec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$searchSpec.matchpattern = “*.vmx”
$task = Get-View ($dsBrowser.SearchDatastoreSubFolders_Task($datastorePath, $searchSpec))

while ($task.Info.State -eq “running” -or $task.Info.State -eq “queued”){
sleep 5

#Execute if the datastore search returned a result
if($ -ne $null){
#Loop for each .vmx found in the datastore search
foreach ($result in ${
#if the file name is not blank and the folder does not contain the word “snapshot”
#note that this skips .vmx files located in NetApp snapshots
if(($result.File -ne $null) -and !($result.FolderPath -match “snapshot”)){
$found = $FALSE

#Look through all the vmx files known to the filer and compare to the current vmx from the search.
foreach($vmx in $vms){
if(($result.FolderPath + $result.File[0].Path) -eq $vmx){
$found = $TRUE
#If a match was found, quit comparing
if ($found) {break}

#if no match was found, put the orphan vmx into a array called row
if (-not $found -and $task.Info.Result[0].File -ne $null){
$vmx = $result.FolderPath + $result.File[0].Path
$row = “” | Select Datacenter, Cluster, Datastore, VMname, VMXpath
$row.Datacenter = $datacenter.Name
$row.Cluster = $cluster.Name
$row.Datastore = $ds.Summary.Name
$row.VMname = (([regex]”(w+).vmx”).Match($result.File[0].Path)).Groups[1].Value
$row.VMXpath = $vmx
$report += $row

$report | Export-Csv “C:Unregistered-VMX.csv” -NoTypeInformation

This entry was posted in Computing, PowerShell, Scripting, Virtualization, VMware and tagged . Bookmark the permalink.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.