Zsoldier
Expert
Expert

Trying Get Folder Path for VM in VC...

Jump to solution

So here is what I'm trying to do. I've seen other posts relating to this, but they only seem to get the immediate parent path rather than the full path. We've basically setup a tree structure like this:

DATA_Center\business_service\SLDC\VM (SLDC = Software Development Cycle)

We've set it up this way so it is easier for admins to find systems related to a particular business service. When a SAN maintenance occurs, we like to inform the business service admins affected by the maintenance. So we basically build a spreadsheet and find all the LUN's attached to that particular SAN, find the VM's, then lookup folder path the VM lies under to find what what business service is affected. I've attached a photo of our VC folder setup as an example.

I was wondering if it was possible through powershell to get a VM's associated folder path like what I have above. I'm able to grab all other information needed, except the folder path. Here is what I have so far:

Get-VM | % {Get-View $_.ID} |

select name,

@{ Name="Datastore";Expression={(Get-Datastore -VM $_.Name).Name}}

(All VMDK's for a server reside on the same datastore so I have no need to look for or list other datastores for a single VM)

I tried messing w/ the script in the below thread for folder pathing, but I can't seem to get what I'm looking for.

http://communities.vmware.com/thread/170864

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

Ok, the following script should do the trick.

One remark though, if a guest is stored over multiple datastores, only the first datastore will be reported.

$report = @()
Get-VM | Get-View | %{
  $row = "" | select Name, Datastore, Path
  $row.Name = $_.Name
  $row.Datastore = (Get-View $_.Datastore[0]).Summary.Name
  $current = Get-View $_.Parent
  $path = $_.Name
  do {
    $parent = $current
	if($parent.Name -ne "vm"){$path =  $parent.Name + "\" + $path}
	$current = Get-View $current.Parent
  } while ($current.Parent -ne $null)
  $row.Path = $path
  $report += $row
}
$report

Note1: that this is the view of the "blue" folders. The "Virtual Machines and Templates" view in the VI client.

Note2: the script suppresses the display of the hidden "vm" folder


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
13 Replies
LucD
Leadership
Leadership

Did you have a look at my script in .

It lists all guests with their complete path and that for the "Hosts & Clusters" view as well as for the "Virtual Machines & Templates" view (blue folders).


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Zsoldier
Expert
Expert

I did not see that. I'll take a look now, thanks. (_)

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
Zsoldier
Expert
Expert

So I finally got a few minutes to look over the script you referenced. It works great for going top down, but I'm looking to get folder pathing the other way around. From VM to top, you think this is doable?

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
LucD
Leadership
Leadership

If I understand it correctly you want the list to be

<VM-name>\<folder-name>\<cluster-name>\<datacenter-name>

instead of

<datacenter-name>\<cluster-name>\<folder-name>\<VM-name>

.

If that is the case, the following script will do that:

function get-children-reverse($entity,$path){
  if($entity.Name -ne "vm"){
	$path = $entity.Name + "\" + $path
  }
  foreach($child in $entity.ChildEntity){
    $childfld = Get-View -Id $child
	switch($childfld.gettype().name){
	  "Folder" {
		Write-Host ($childfld.Name + "\" + $path)
		get-children-reverse $childfld $path
	  }
         "VirtualMachine"{
		$vm = $childfld.Name + "\" + $path
                Write-Host $vm
	  }
	  "Datacenter"{
		Write-Host ($childfld.Name + "\" + $path)
                get-children-reverse $childfld $path
	  }
	  "ClusterComputeResource" {
		Write-Host ($childfld.Name + "\" + $path)
                foreach($esxMoRef in $childfld.Host){
                     $esx = Get-View -Id $esxMorEF
		     $h = $esx.Name+ "\" + $childfld.Name + "\" + $path
		     Write-Host $h
		 }
	  }
     }
  }
}

# Virtual machines & Templates

Write-Host "Virtual Machines & Templates`n"
Get-Datacenter | %{
  $dc = Get-View -Id ($_).id
  $folder = Get-View -Id $dc.VmFolder
  get-children-reverse $folder $dc.Name
}

# Hosts & Clusters

Write-Host "`nHosts & Clusters`n"
Get-Datacenter | %{
  $dc = Get-View -Id ($_).id
  $folder = Get-View -Id $dc.HostFolder
  get-children-reverse $folder $dc.Name
}

Note: if you only want VMs and Templates to be listed it can be done easily by removing the Write-Host cmdlets in the get-children-reverse function except for the "VirtualMachine" case.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Zsoldier
Expert
Expert

Err, not exactly looking for just semantics. What I meant was using my above script, I'm looking for systems that are inside certain datastores. I think I can use your script, but I don't have an idea as how to reference the objects outputted by your function. For instance:

$VIserver = Read-Host "VC Server Name"

connect-viserver -server $VIserver

Get-VM | % {Get-View $_.ID} |

select name,

@{ Name="Datastore";Expression={(Get-Datastore -VM $_.Name) | where {$_.Name -inotmatch 'nfs_share'}}}

This outputs a table that lists a VM's Name and the name of the datastore where the VM resides. I want to add folder path to this. Using your function I was trying to do something like this:

@{ Name="Path";Expression={Get-Datacenter | % {(get-children $_.VmFolder $_.Name) | where {$_ -contains '$_'} }}}

Basically to only output the path that contains the VM's name. I'm pretty sure I'm screwed up on the where command if not elsewhere.

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
LucD
Leadership
Leadership

Before I start coding, you want a report showing

Name                         Path
VM1                          datacenter1\folder1\VM1
VM2                          datacenter1\folder2\VM2
VM3                          datacenter2\folder2\VM3

Did I understand it correctly now ?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
Zsoldier
Expert
Expert

Yeppers. Datastore column as well.

Thanks.

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
LucD
Leadership
Leadership

Ok, the following script should do the trick.

One remark though, if a guest is stored over multiple datastores, only the first datastore will be reported.

$report = @()
Get-VM | Get-View | %{
  $row = "" | select Name, Datastore, Path
  $row.Name = $_.Name
  $row.Datastore = (Get-View $_.Datastore[0]).Summary.Name
  $current = Get-View $_.Parent
  $path = $_.Name
  do {
    $parent = $current
	if($parent.Name -ne "vm"){$path =  $parent.Name + "\" + $path}
	$current = Get-View $current.Parent
  } while ($current.Parent -ne $null)
  $row.Path = $path
  $report += $row
}
$report

Note1: that this is the view of the "blue" folders. The "Virtual Machines and Templates" view in the VI client.

Note2: the script suppresses the display of the hidden "vm" folder


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
Zsoldier
Expert
Expert

Dude, that is awesome. Thanks.

Chris Nakagaki (中垣浩一)
Blog: https://tech.zsoldier.com
Twitter: @zsoldier
0 Kudos
mwent46
Contributor
Contributor

Is it also possible to get the annotations with that.

thanx

0 Kudos
BaluVirigineni
Enthusiast
Enthusiast

Hi LucD,

I am trying to move VMs to their respective folders after deploying from Template, however we have multiple folders by the same name in the Datacenter, hence tried your Get-Folder path..but didnt work for me. Can you help me in this.

I want to move VM like this Datacenter\Folder1\Folder2\Folder3..

Below is the PowerCLI Script I used, I just ran the script in PCLI and tried to ran Get-FolderByPath cmdlet,  but it is saying that there is no such cmdlet or 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 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} = '/'

  )

  process{

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

      $vcs = $defaultVIServers

    }

    else{

      $vcs = $defaultVIServers[0]

    }

    foreach($vc in $vcs){

      foreach($strPath in $Path){

        $root = Get-Folder -Name Datacenters -Server $vc

        $strPath.Split($Separator) | %{

          $root = Get-Inventory -Name $_ -Location $root -Server $vc -NoRecursion

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

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

          }

        }

        $root | where {$_ -is [VMware.VimAutomation.ViCore.Impl.V1.Inventory.FolderImpl]}|%{

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

        }

      }

    }

  }

}

0 Kudos
LucD
Leadership
Leadership

See my reply (with example) on the other thread where you raised this question.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
rachappachalmi
Enthusiast
Enthusiast

Hi LucD,

I also have the same requirement as this thread but I need to list all the datastore where VMs active files are residing, because SimpliVity restore dont support if the active files of the VMs are in multiple folders in same datastore or different datastores. can you help me with this pls.

0 Kudos