2 Replies Latest reply on Feb 12, 2020 1:03 PM by JBartholomew

    Issues with Get-FolderbyPath when connected to multiple vCenters

    JBartholomew Novice

      I am currently in the process of creating a script to automate batch creation of our VMs in various vCenters, and have reached the point where the VM Creation is doing exactly what I need, but it is still creating the VM in the root folder within the vCenter.

       

      I started looking around for solutions on how to move the VM to the correct folder, or create the VM in the correct folder from the start, and came across the Get-FolderbyPath function created by LucD.

       

      I started playing around with the function, and am struggling to get it to give me exactly what I need.

       

      The biggest part of the issue is that our folder structure within each vCenter is a.) very similar to each other, and b.) each vCenter contains many of the same folder names

       

      Our Folder layout is Datacenter/Company/Project/Environment, and so as a rough example we have folders called:

      Paris/Company/Project/Environment

      Ottawa/Company/Project/Environment

       

      So if I am connected to only the Paris vCenter and run Get-FolderbyPath -Path "Paris/Company/Project/Lab" I get only one result and if I pipe that to a Get-VM I can verify that I only see the VMs I expect to be seeing.

       

      But if I am connected to vCenter using -allLinked and run the same command I get multiple results, and I believe I have narrowed down what is happening, but I am not sure why.

       

      When running the Get-folderbypath when connected to multiple vCenters the below is what is happening

       

      If I am looking for "Paris/Company/Project/Lab" as a path, when the script runs through the Paris vCenter I only get one result (the expected result), but then the script runs through against the Ottawa vCenter, and if it does not have an exact "Company/Project/Lab" path it returns any folder that is named "Lab" no matter where its located, so the Folder results are as below:

      IE.)

      Paris/Company/Project/Lab

      Ottawa/Company/Project2/Lab

      Ottawa/Company/Project5/Lab

      Ottawa/Company4/Project/Lab

       

      The very strange part is that we also have folders such as below that are NOT being returned by the Get-Folderbypath function:

      Paris/Company/Project2/Lab

      Paris/Company2/Project/Lab

      Paris/Company4/Project5/Lab

       

      But if we do have an exact "Company/Project/Lab" Path in both vCenters the results are

      Paris/Company/Project/Lab

      Ottawa/Company/Project/Lab

       

      and in this case the

      Ottawa/Company/Project2/Lab

      Ottawa/Company/Project5/Lab

      Ottawa/Company4/Project/Lab

      Paths are not shown.

       

      So I am trying to figure out how to get the Get-folderbypath function to only give me Paris/Company/Project/Lab when connected to multiple vCenters or if that exact path doesn't exist, return 0 entries so I know it doesn't exist so I can instruct my script to create the new folder as required.

        • 1. Re: Issues with Get-FolderbyPath when connected to multiple vCenters
          LucD Guru
          User ModeratorsCommunity WarriorsvExpert

          I just added the Server parameter to the function.
          See it that can solve your issue.

           

          Now you can do

           

          Get-FolderByPath -Path 'DC//Folder1' -Server 'vcsa.domain'

           

          and also

           

          Get-FolderByPath -Path 'DC/Homelab/Folder1' -Server $global:defaultVIServer

           

          The updated function

           

           

          function Get-FolderByPath {

          <#

          .SYNOPSIS Retrieve folders by giving a path

          .DESCRIPTION The function will retrieve a folder by it's path.

             The path can contain any type of leave (folder or datacenter).

          .NOTES

             Author: Luc Dekens

          .PARAMETER

             Path The path to the folder. This is a required parameter.

          .PARAMETER

             Separator The character that is used to separate the leaves in the path. The default is '/'

          .EXAMPLE

             PS> Get-FolderByPath -Path "Folder1/Datacenter/Folder2"

          .EXAMPLE

             PS> Get-FolderByPath -Path "Folder1>Folder2" -Separator '>'

          #>

           

              param(

                  [CmdletBinding()]

                  [parameter(Mandatory = $true)]

                  [System.String[]]${Path},

                  [char]${Separator} = '/',

                  [PSObject]$Server

              )

           

              process {

                  if ($Server) {

                      if ($Server -is [String]) {

                          $vcs = $global:defaultVIServers | Where-Object { $_.Name -eq $Server }

                      }

                      else {

                          $vcs = $Server

                      }

                  }

                  else {

                      if ((Get-PowerCLIConfiguration).DefaultVIServerMode -eq "Multiple") {

                          $vcs = $global:defaultVIServers

                      }

                      else {

                          $vcs = $global:defaultVIServers[0]

                      }

                  }

           

                  foreach ($vc in $vcs) {

                      $si = Get-View ServiceInstance -Server $vc

                      $rootName = (Get-View -Id $si.Content.RootFolder -Property Name).Name

                      foreach ($strPath in $Path) {

                          $root = Get-Folder -Name $rootName -Server $vc -ErrorAction SilentlyContinue

                          $strPath.Split($Separator) | ForEach-Object {

                              $root = Get-Inventory -Name $_ -Location $root -Server $vc -ErrorAction SilentlyContinue

                              if ((Get-Inventory -Location $root -NoRecursion | Select-Object -ExpandProperty Name) -contains "vm") {

                                  $root = Get-Inventory -Name "vm" -Location $root -Server $vc -NoRecursion

                              }

                          }

                          $root | Where-Object { $_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl] } | ForEach-Object {

                              Get-Folder -Name $_.Name -Location $root.Parent -NoRecursion -Server $vc

                          }

                      }

                  }

              }

          }

          Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
          • 2. Re: Issues with Get-FolderbyPath when connected to multiple vCenters
            JBartholomew Novice

            Luc,

            You never fail to amaze me. This is exactly what was required as I realized part of the flaw in my logic was that I was looking for the vCenter name as the root of the path, when it is actually the hidden "Datacenters" folder and so there isn't really a way to define which vcenter root it is just by path. This will work for my purposes as I will be able to inject the logic to determine from the VM Tags what vCenter should be used and use that for the $server variable.