Finding and creating vCenter folders by path

VMware folders are quite awkward to deal with, due to the fact that each folder has it's own object ID, and then a reference to its parent ID. There doesn't appear to be any master store of the full path to a folder, so you have to work your way up the hierarchy to figure out where a folder is located.

As good as VMware's PowerCLI is, it doesn't appear to have any way to specify a folder to use, by path, so we have to figure out folder paths ourselves.

If you run the PowerCLI cmdlet "get-folder -name 'foldername'" against vCenter, there is a good chance you will receive multiple objects in return, because it will find any folder in the hierarchy matching that name.

Let's say you want to place your new VM in /myVMs/Prod/SQL

If you try to "get-folder" on the "SQL" folder, you may receive:


Name                           Type           
----                           ----           
SQL                            VM             
SQL                            VM 
SQL                            VM   

How do you know which one to pick?

Well, you could look at each object and check its parent folder:


$folders[0].parent

Name                           Type           
----                           ----           
Test                           VM             


$folders[1].parent

Name                           Type           
----                           ----           
Prod                           VM  


In this case, the second item is probably the one you want to use - but you'd probably still want to check the parent of THAT folder to ensure it comes back with "myVMs".

Here's a quick function to do this all for you, and all you have to do is enter the full path of the folder you want.

If the folder doesn't exist, it creates it. If it does exist, it simply returns that final folder object for you to use elsewhere.



function New-vCenterFolderByPath{

  param(
  [parameter(Mandatory = $true)]
  [String]$FolderPath,
  [char]$Delimeter = '/',
  [parameter(Mandatory = $true)]
  [String]$vCenter
  )

    $datacenter = get-datacenter

    #get the first "vm" folder under the datacenter
    $rootFolder = get-folder -Name "vm" -Location $datacenter -Type vm | where {$_.parent.name -eq $datacenter.name}

        #Split the folder path you entered, by the delimeter, into an array
        $folderItems = $Folderpath.Split($Delimeter)



        #Step through each item in the array
        foreach($folderItem in $folderItems)
       {
          #If folderItem is empty, skip (empty items could occur if user enters the delimeter at the beginning or end of the path)
          if($folderItem -ne "")
          {
              #Set the previous root folder, so we can use it if we need to create a new folder
              $prevroot = $rootFolder
              $rootFolder = Get-Folder -Name $folderitem -Location $rootFolder -Server $vCenter -NoRecursion -ErrorAction SilentlyContinue
              if(!$rootFolder)
              {
                #if folder not found, create it
                New-Folder -Name $folderitem -Location $prevroot -Server $vCenter
                $rootFolder = Get-Folder -Name $folderitem -Location $prevroot -Server $vCenter -NoRecursion
              }
          }

        }


     return $rootFolder

}


You would call the above function using:


new-vCenterFolderByPath -FolderPath "MyVMs/Prod/SQL" -vcenter YourVcenterName

The function returns the object of the folder that you would then use with other cmdlets such as new-vm.