Isn’t it annoying when you are looking for a VM on your datastore and you cant find it because the folder name is not the same as the VM, use the below script and you will never have that problem again.
This script will compare the name of the VM to the folder it is stored in, any mismatches will be output.
I know a regex expert could probably do this better, let me know if you are one 🙂
Sample Output:
VM | Path |
New VM 1 | [storage1] New VM |
ABCDEV01 | [storage1] Dev Test |
MicroDS | [SAN11] New VM |
VM127 | [SAN11] Windows 2003 Server |
Code:
Connect-VIServer MYVISERVER
$VMFolder = @()
Foreach ($VM in (Get-VM |Get-View)){
$Details = “” |Select-Object VM,Path
$Folder = ((($VM.Summary.Config.VmPathName).Split(‘]‘)[1]).Split(‘/‘))[0].TrimStart(‘ ‘)
$Path = ($VM.Summary.Config.VmPathName).Split(‘/‘)[0]
If ($VM.Name-ne $Folder){
$Details.VM= $VM.Name
$Details.Path= $Path
$VMFolder += $Details
}
}
$VMFolder |Export-Csv -NoTypeInformation C:\temp\Mismatch.csv
Pingback: Virtual Spring Cleaning - Organization within vSphere | VMware vSphere Blog - VMware Blogs
Nice scripts . Very helpful.
Ashraf
Thanks Luc
Yeah, it might be encoding or something of that nature. I copied from another blog that linked back to this page and it worked. Odd.
Just tried it against mine, all is fine, copy and paste issue ?
Is this working for anyone in vcenter/powercli 5.0? Has worked for me before in 4.1 but not now.
I’m getting a “Missing ‘)’ in method call.” error line 5 character 51
Pingback: VM folder name mismatch query using PowerShell - motogobi
Doh, looks like the code was broken a bit due to interpreted/discarded angle brackets . That last part should have been something like:
…(50% fewer calls to “match”). And, for clarity’s sake, you could add some named capture groups (such as “?<path>“):
if ($VmPathName -match “(?<path>\[.+\] (?<folder>.+))/”) {$Folder = $Matches[‘folder’]; $Path = $Matches[‘path’];}
…that is, if I have it right, now (no preview for this comment).
Hello-
@Harley
You should probably be able to change the regex from using word characters to using any, since the matching/grouping in this instance is based on the “] ” and the trailing “/”. That is, like so:
…
$VmPathName = $VM.Summary.Config.VmPathName
$Folder = ([regex]”\[.+\] (.+)/”).match($VmPathName).Groups[1].Value
$Path = ([regex]”(\[.+\] .+)/”).match($VmPathName).Groups[1].Value
…
For efficiency’s sake, you could also write it as:
…
if ($VmPathName -match “(\[.+\] (.+))/”) {$Folder = $Matches[2]; $Path = $Matches[1];}
…
(50% fewer calls to “match”). And, for clarity’s sake, you could add some named capture groups (such as “?”):
…
if ($VmPathName -match “(?\[.+\] (?.+))/”) {$Folder = $Matches[‘folder’]; $Path = $Matches[‘path’];}
…
Matt
Thank you for the awesome script!
@LucD
Thank you for the regex LudD. However, I am having some problems with the matching when there is a non-word character (e.g. dash or underscore) in the VM Name. Any suggestions?
@Alex
Thanks for the kind comments
You think of everything that’s annoyed me in the last couple of years. Perfect and thanks again. Glad I found this site.
@amusica
Consistency is the key, thanks for the comment.
This is a pet peeve of mine for a while now, I am very anal about VMs like this I always end up changing the names of the directory name or even filename’s by either svmotioning or using vmkfstools to match GUI (presumably what I wanted!)
Thanks the for the article.
@LucD
As always AMAZING ! Thanks Luc
A very “usable” article.
And for completeness sake, the regex version:
…
$VmPathName = $VM.Summary.Config.VmPathName
$Folder = ([regex]”\[\w+\] (\w+)/”).match($VmPathName).Groups[1].Value
$Path = ([regex]”(\[\w+\] \w+)/”).match($VmPathName).Groups[1].Value
…
Regex is your friend 😉