PowerCLI: Folder Name Mismatch

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

16 thoughts on “PowerCLI: Folder Name Mismatch”

  1. 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.

  2. 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

  3. …(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’];}

    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).

  4. 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

  5. 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?

  6. 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.

  7. 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 😉

Leave a Reply