Thanks for your reply Alex. I took a stab at letting AI fix it. See below, now I think the issue is related to using the "Import-CSV" cmdlet. When I use Export-CSV to export the output, it shows as numbers.
# Requires the VMware PowerCLI module
Import-Module VMware.PowerCLI
# NOTE: Ensure you are connected to vCenter via Connect-VIServer -Server <vCenterName>
# --- Configuration Variables ---
$ClusterName = "TEST"
# Use a wildcard for the datastore pattern
$DatastorePattern = "snap*"
$VMFolderName = "Recovery"
# Path to the CSV file containing the names of the VMs you want to find
$InputCSVPath = "C:\Input\Master.csv"
# --- Pre-requisite Setup ---
# Get the target ESX host (the first host found in the cluster)
$ESXHost = Get-Cluster $ClusterName | Get-VMHost | Select-Object -First 1
if (-not $ESXHost) {
Write-Error "Could not find a valid ESX host in cluster $ClusterName."
exit
}
# Ensure the target VM folder exists, create it if not
$TargetVMFolder = Get-Folder -Name $VMFolderName -ErrorAction SilentlyContinue
if (-not $TargetVMFolder) {
Write-Host "Creating VM folder: $VMFolderName"
$TargetVMFolder = New-Folder -Name $VMFolderName
}
# Load the desired VM names from the input CSV into an array
# Assuming the CSV has a column header named 'Name' (adjust 'Name' if needed)
try {
$TargetVMNames = Import-Csv -Path $InputCSVPath | Select-Object -ExpandProperty Name
} catch {
Write-Error "Failed to import CSV file from $InputCSVPath. Check file path and format."
exit
}
# Array to store the paths of the found VMX files
$FoundVMXFiles = @()
# --- Search Logic ---
Write-Host "Starting search for VM names listed in $InputCSVPath..."
# Set up the search criteria once
$SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$SearchSpec.matchpattern = "*.vmx"
# Iterate through all datastores matching the pattern
foreach ($Datastore in Get-Datastore -Name $DatastorePattern) {
Write-Host "Searching datastore: $($Datastore.Name)..."
# Get the view/internal object reference for the datastore browser
$dsBrowser = Get-View $Datastore.Extensiondata.Browser
# Define the base path for the search
$DatastorePath = "[" + $Datastore.Name + "]"
# Execute the search using the API method SearchDatastoreSubFolders
# We use a Where-Object filter immediately to remove snapshot folders
$searchResults = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) |
Where-Object { $_.FolderPath -notmatch ".snapshot" }
# Process the results
foreach ($folder in $searchResults) {
foreach ($file in $folder.File) {
$vmxPath = $folder.FolderPath + $file.Path
# Extract the VM name guess from the folder path containing the VMX file
$vmNameGuess = ($vmxPath.Split('/')[-2]).Trim()
# Check if this VM name is in our target list from the CSV
if ($vmNameGuess -in $TargetVMNames) {
Write-Host " [+] Match found: $vmNameGuess at $vmxPath"
$FoundVMXFiles += $vmxPath
}
}
}
}
# --- Registration Logic ---
if ($FoundVMXFiles.Count -eq 0) {
Write-Warning "No matching VMX files were found."
} else {
Write-Host "Registering $($FoundVMXFiles.Count) found VMs..."
foreach ($VMXFile in $FoundVMXFiles) {
# Use New-VM to register the VM from its VMX file path
# It's helpful to explicitly name the VM using our guess to match the input CSV name expectation
$registerName = ($VMXFile.Split('/')[-2]).Trim()
Write-Host "Registering $registerName from $VMXFile..."
New-VM -Name $registerName -VMFilePath $VMXFile -VMHost $ESXHost -Location $TargetVMFolder -RunAsync
}
Write-Host "VM registration process initiated."
}
-------------------------------------------
Original Message:
Sent: Dec 11, 2025 03:17 AM
From: Alex Sons
Subject: Add VMs to Inventory PoSh
Well, I took a different approach when searching for files on a datastore.
Basically I mount each datastore (New-PSDrive) and use standard Powershell commands (Get-ChildItem) to find the files I'm searching for.
Something like:
$vcname = YourVCName
$dsname = YourDatastoreName
$vc = connect-viserver $vcname
$dsobject = Get-Datastore -Name $dsname -Server $vc
$psdrive = New-PSDrive -datastore $dsobject -Name $dsobject.Name -PSProvider VimDatastore -Root \
$vmxlist = Get-ChildItem ${psdrive}:\ -Include *.vmx -Recurse
$vmxlist |select Name, FolderPath
You may want to 'enhance' the -Include statement in order to limit the search path.
Or you could just omit the -Include part, collect a list of all files and then select the vmx files.
Original Message:
Sent: Dec 10, 2025 03:10 PM
From: Roger Haines
Subject: Add VMs to Inventory PoSh
Anyone? I'm stumped!
Any help would be greatly appreciated!
Original Message:
Sent: Dec 09, 2025 02:59 PM
From: Roger Haines
Subject: Add VMs to Inventory PoSh
I want to modify the script below to include all the servers from a CSV file in the format below, then everything included in the "SearchResult" line in the script. ie.. "$SearchResult = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {$_.FolderPath -notmatch ".snapshot"} | %{$_.FolderPath + ($_.File | select Path).Path}"
Name
server1
server2
server3
server4
server5
$Cluster = "TEST"$Datastores = "snap*"$VMFolder = "ReplicationRecovery"$ESXHost = Get-Cluster $Cluster | Get-VMHost | select -First 1$RGMachines = Get-Content C:\MasterRG.csv 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 }}
I suspect I need to add something like below, but need some help. @LucD
Where-Object { $_.Name -in $vmList }
-------------------------------------------