Get the folderpath

A useful property that is obviously missing from the Get-Folder cmdlet, is the path of the folder. In the PowerCLI Community there are regularly threads that ask for this kind of information. Most of the time it concerns scripts to export/import folder structures or scripts to migrate vCenters.

Another property that is obviously missing, is the indication if a specific folder is a so-called “blue” or “yellow” folder.

To solve this problem once and for all, I wrote this short function, called Get-FolderPath, that will return you both of these properties.

The script

Annotations

Line 1: The function requires PowerCLI 4.1

Line 26-29: The function can be used in a pipeline and requires one or more FolderImpl objects on the -Folder parameter .

Line 34: With the use of the -ShowHidden parameter the function can include the hidden folders in the folderpath. This array contains the names of the hidden folders.

Line 41-43: To determine if a folder is yellow or blue, the script tests for the presence of VirtualMachine in the ChildTypes of the folder.

Line 45-50: The script moves towards the root of the vSphere environment. When there is no Parent present on an entity, the script knows it has reached the beginning of the folderpath.

Line 47: The test that decides if a foldername will be included in the path or not.

Samples

The use of the function is quite straightforward.

The returned object contains the basic information, name of the folder, the folderpath and the type of the folder.

We can use the -ShowHidden parameter to display the “hidden” folders in the path.

And the script can of course also be used in a pipeline construct.

The function is handy to find folders with identical names. The Folderpath property makes it easy to locate these.

And you can of course ask for a complete list of the folders defined on your vCenter.

You can easily use this function in combination with other cmdlets.
Let’s for example list all the “blue” folders in a specific datacenter.

Enjoy !

27 Comments

    Mark

    @Matthew Tiffany

    Hi Matthew Your add-on script is exactly what I am looking for. However, every time I use it the “path” column is empty for all VMs. If I run $folders it shows the folders and folder paths so the information is there. I’ve tried with the function you added as part of the script. I’ve tried running the function at the PowerCLI command line. I’ve tried importing the function as a module into PowerCLI and then calling the function from the script. The path column in results always ends up empty. Any ideas?

    Denis

    Hi Luc,
    I try to use your function in a mutliconnection environnement and get a error messages in loop:

    Get-View : Cannot validate argument on parameter ‘VIObject’. The argument is null, empty, or an element of the
    argument collection contains a null value. Supply a collection that does not contain any null values and then try
    the command again.
    + $fld = Get-View $fld.Parent
    + ~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [Get-View], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNet
    Interop.GetVIView
    Thanks in advance for your help
    Best Regards
    Denis

    Ron Klimaszewski

    Great script. Without the datacenter folder there is a missing link back to the root level. I added an End{} block to retrieve this information. In the version below I also changed your ‘Type’ column to the actual folder type, moving the color to info to a ‘Color’ column. I also added the FolderId and ParentFolderId information.

    function Get-FolderPath {

    param (
    [parameter(valuefrompipeline = $true,
    position = 0,
    HelpMessage = “Enter a folder”)]
    [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl[]]$Folder,
    [switch]$ShowHidden = $false
    )

    begin {
    $excludedNames = “Datacenters”, “vm”, “host”
    $hash = @{ };
    }

    process {
    $Folder | %{
    $fld = $_.Extensiondata
    $fldColor = “yellow”
    if ($fld.ChildType -contains “VirtualMachine”) {
    $fldColor = “blue”
    }
    $path = $fld.Name
    while ($fld.Parent) {
    $fld = Get-View $fld.Parent
    if ((!$ShowHidden -and $excludedNames -notcontains $fld.Name) -or $ShowHidden) {
    $path = $fld.Name + “\” + $path
    }
    }
    $row = “” | Select Name, Path, Color, Type, Id, ParentId
    $row.Name = $_.Name
    $row.Path = $path
    $row.Color = $fldColor
    $row.Type = $_.Type
    $row.Id = $_.Id
    $row.ParentId = $_.ParentId
    $hash.Add($_.Id,$_.Name)
    $row
    }
    }

    end {
    Get-Datacenter | %{

    $row = “” | Select Name, Path, Color, Type, Id, ParentId
    $row.Name = $_.Name
    $row.Path = $hash.Item($_.ParentFolderId) + “\” + $_.Name
    $row.Color = “yellow”
    $row.Type = “Datacenter”
    $row.Id = $_.Id
    $row.ParentId = $_.ParentFolderId
    $row

    }

    }
    }

      LucD

      Thanks for sharing that useful improvement.

    jeff mcdermott

    I installed powershell 4 & powercli 5.5u2 but running get-pssnapin shows vmw* as psversion 2.0 despite Microsoft components showing as psversion 4.0

    so I do not understand how to satisfy the requirement 4.1 stmt on line 1 of get-folderpath & get the following error

    PowerCLI C:\windows\system32> . get-folderpath.ps1
    . : The script ‘get-folderpath.ps1’ cannot be run because the following
    snap-ins that are specified by the “#requires” statements of the script are
    missing: VMware.VimAutomation.Core (Version 4.1).
    At line:1 char:3
    + . get-folderpath.ps1
    + ~~~~~~~~~~~~~~~~~~
    + CategoryInfo : ResourceUnavailable: (get-folderpath.ps1:String)
    [], ScriptRequiresException
    + FullyQualifiedErrorId : ScriptRequiresMissingPSSnapIns

      LucD

      Hi Jeff, just leave out that line.
      It was added at the time to make sure you had at least PowerCLI v4.1, but by now everyone should be running a more recent version I guess.

    Matthew Tiffany

    Thanks LucD,
    Your posts and scripts around here and the powercli forums have really helped out. This function is no different. In fact it helped me take a script I had from 6 hours to run to around 15 mins.

    Mainly it’s because we’re using folder paths to identify who owns what VM so when I collect a list of VMs also been the Paths, before it would process the path each time but I figured getting a list the folders and processing the paths than just matching them to the VMs would be faster. Here the script incase anyone else is interested.

    $date = Get-Date -format M-d-yyyy

    . “C:\chargeback\Chargeback Scripts\Get-FolderPath.ps1″

    $folders = Get-Folder -type vm | Get-FolderPath | Sort-Object Id

    function Set-Path{
    param($Object)
    foreach ($folder IN $folders){
    if( $folder.Id -eq $Object.Id){
    $result = $folder.Path
    break
    }
    }
    $result
    }

    Get-VM | Sort-Object FolderID | Select Name, Uid, NumCpu, MemoryGB, ProvisionedSpaceGB, @{N=”Path”;E={Set-Path -Object $_.Folder}}, ResourcePoolId, ResourcePool, @{N=”ToolsStatus”;E={$_.ExtensionData.Summary.Guest.ToolsVersionStatus}} | `
    Export-Csv “C:\vServerCSVs\ashburn-vServer-$date.csv” -NoTypeInformation -UseCulture

    Philip

    Hi Luc

    I know this a well tried and tested script, however I am getting some strange results, no doubt because of my environment.

    I am trying to migrate form one VC to a new VC, I have used the Cheap DR Scrips (http://www.gabesvirtualworld.com/cheap-disaster-recovery/) but it fails beacuse we have duplicate folders

    I wanted to modify these scripts and use your get-folderbypath function to help resolve this.

    We have a folder structure, as sample of which is as follows:

    DataCenter1
    Customer1
    Production
    SubTeam1
    Production

    If I run you script get-folderbypath -Path “DataCenter1\Customer1\Production” it gives me the following results

    Name Type
    —- —-
    Production VM
    Production VM

    Which is not as I expected, it seem to recuse to the subteam1 folder rather than return the folder id of the path entered

    Could you help please?

      LucD

      Hi Philip,
      Are you sure you didn’t mean the function in Folder by Path ?
      And by coincidence we had a similar comment on there, and the user even found the solution.
      See the -NoRecursion switch you can add.

    YWM

    Hi Lucd, I also try to use your script to export the folder from VCenter, but I got many error and can’t export the result. I check the attached script file and find that there are many corruption word (ame?) like below in the script. How can I resolve it? Thank you.

    https://communities.vmware.com/thread/268411

    $ret | Add-Member -Type noteproperty -Name ame?-Value $role.name
    $ret | Add-Member -Type noteproperty -Name abel?-Value $role.info.label
    $ret | Add-Member -Type noteproperty -Name ummary?-Value $role.info.summary
    $ret | Add-Member -Type noteproperty -Name oleId?-Value $role.roleId
    $ret | Add-Member -Type noteproperty -Name ystem?-Value $role.system
    $ret | Add-Member -Type noteproperty -Name rivilege?-Value $role.privilege

    YWM

    Dear LucD,
    I’m going to move all ESX host and VMs from VCenter 4.1(under the same domain) to new Virtual Centre 5.1(under the same domain). Is there a migrate script or easy way that I can move them and place VMs in correct folder and apply the role attributes/ folder permissions back into the new VC server?
    move steps like below:
    1.Export folders
    2.Export VM locations in Folders
    3.Export Permissions
    4.Export Custom Attributes
    5.Create Folders on the new vCenter
    6.Disable DRS/HA
    7.Remove ESX hosts from Source vCenter and add to Destination vCenter
    8.Enable DRS/HA again
    9.Move all vm’s to correct folders
    10.Apply the permissions back
    11.Apply custom attributes and notes

    Sorry, my english isn’t well, hope you can understand and really appreciate your help. Thanks!

    brendan62269

    Luc;
    You rock!

    Arvinth

    Thanks For the reply Luc,

    I was searching for this option a long time and finally came to know from you its the problem with Vsphere.

    I would like to comment that your forums and scripts is saving the day of many administrators.

    especially I have learnt many stuffs from your forums and benefited.. Keep rocking Friend.

    wish you a happy advance x-mas & great new year a head.

      LucD

      Thanks, much appreciated.
      Glad you find my posts useful.

    Arvinth

    Luc,

    Is there any option to find out who has moved the VM from a folder A to the folder B using power CLI

      LucD

      @Arvinth, well there is the Tasks and Events you query for all MoveIntoFolder_Task entries, but unfortunately the VM property seems to be empty in the Task object and in the related Events. The target folder is available.

      This is not a PowerCLI problem, but it appears to be a vSphere problem.

    Jason

    This is great. Works perfectly for export. How do I create a blue folder with the new-folder cmdlet?

    AnasAA

    we assume that there are two blue folders:
    DC1\Folder\Folder171 and DC1\Folder\Folder1\Folder171

    Now i would like to move a VM1 to e.g. DC1\Folder\Folder1\Folder171 per script.
    How can i do that?

    Thanks

      LucD

      @AnasAA, you could do something like this

      $source = "DC1\Folder\Folder171"
      $destination = "DC1\Folder\Folder1\Folder171"
      $srcFld = Get-Folder -Name Backup | where {(Get-FolderPath -Folder $_).Path -eq $source}
      $dstFld = Get-Folder -Name Backup | where {(Get-FolderPath -Folder $_).Path -eq $destination}
      Get-VM -Name VM1 -Location $srcFld | Move-VM -Destination $dstFld -Confirm:$false

    Robin

    Thanks so much, as always Luc! I’ve used this to export text file lists of VMs based on them belonging to blue folders (with some exclusions also) 🙂

    Suresh

    Very nice script Luc. Thanks!

    Doug Youd

    Nice script. I’ll be using it shortly as part of an automated “clone workload to test” procedure. So thanks for making my life that little bit easier. 🙂
    -Cni

    Eugene

    How do I register this custom Get-FolderPath function in order to use it?

      LucD

      @Eugene, there are several ways you can make this function available.
      1) Place it in one of your profile files.
      2) Save the function in a .ps1 file and then dot-source the file (PS> . Get-FolderPath.ps1).
      In both cases you will be able to call the function in your scripts or from the prompt.
      3) Insert the function in your script. Make sure the function comes before the first call to it.

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

Buy the Book