VMware Cloud Community
jnewton20111014
Contributor
Contributor
Jump to solution

Folder a VM is in using Get-View

All, I run a script to gather information about VMs within the environment but have not been able to figure out how to get the folder the VM is in.  I know I could use a get-vm | select Name, Folder etc but the moment I add a get-vm statement I'm going to add a TON of run time to the script.

I'm currently using this as my get-view command...

Get-View -ViewType VirtualMachine -Property Name,Runtime.Host,Config.GuestFullName,Config.Annotation,Config.Hardware.NumCPU,Config.Hardware.MemoryMB,Guest.Disk,Config.Template,Guest.IpAddress | Sort-Object -Property Name | %{
if ($_.Config.Template -ne $true) {
$row = "" | Select-Object Name,Notes,MemoryGB,Host,CPUs,OS,Cluster,IPAddress,DiskSpaceGB,UsedSpaceGB

....

I know I'm just grabbing certain properties but I haven't been able to find the property that gives the Folder name.

To try and find the right one I've done

$vm = Get-View -ViewType VirtualMachine -Filter @{"Name"="VM_Name"}

Then just walked through the variable $vm.(Property)  etc.

Anyone?

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

In the VirtualMachine object the Parent property contains the MoRef (pointer) to the Folder object.

So you could

Select Name,@{N="Folder";E={Get-View $_.Parent | Select -ExpandProperty Name}}


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

View solution in original post

0 Kudos
11 Replies
LucD
Leadership
Leadership
Jump to solution

In the VirtualMachine object the Parent property contains the MoRef (pointer) to the Folder object.

So you could

Select Name,@{N="Folder";E={Get-View $_.Parent | Select -ExpandProperty Name}}


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

0 Kudos
jnewton20111014
Contributor
Contributor
Jump to solution

Awesome! Used that information to get it working...

However I think I've added more time to my script with more Get-View commands.  While I'm happy that it "Works" I'd love to get the speed out of it.  Am I doing anything wrong here with these commands?  You can see how I was gathering the information before with a If statement.

Get-View -ViewType VirtualMachine -Property Name,Runtime.Host,Config.GuestFullName,Config.Annotation,Config.Hardware.NumCPU,Config.Hardware.MemoryMB,Guest.Disk,Config.Template,Guest.IpAddress,Parent | Sort-Object -Property Name | %{
if ($_.Config.Template -ne $true) {
$row = "" | Select-Object Name,Notes,MemoryGB,Host,CPUs,OS,Cluster,Folder,IPAddress,DiskSpaceGB,UsedSpaceMB
#$esx = Get-View $_.Runtime.Host -Property Name,Parent
#if ($esx -eq $null) { $row.Host = "Host Error" } else { $row.Host = $esx.Name }
#if ($esx -eq $null) { $row.Cluster = "Cluster Error" } else { $row.Cluster = (Get-View $esx.Parent).Name }
$row.Host = Get-View $_.Runtime.Host | Select -ExpandProperty Name
$row.Folder = Get-View $_.Parent | Select -ExpandProperty Name
$row.Cluster = (Get-View(Get-View $_.Runtime.Host).Parent).Name
$row.Name = $_.Name

.

.

.

What I don't like is I'm running Get-View 4 times after the 1st time to gather the needed information.  Ideas on how to get it to run faster?

0 Kudos
RvdNieuwendijk
Leadership
Leadership
Jump to solution

I think in this case Get-VM is faster than Get-View. And also much easier to program.

Get-VM | Select-Object -Property Name,VMHost,@{N="Cluster";E={$_.VMHost.Parent}},Folder

Blog: https://rvdnieuwendijk.com/ | Twitter: @rvdnieuwendijk | Author of: https://www.packtpub.com/virtualization-and-cloud/learning-powercli-second-edition
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm afraid you'll have to live with the multiple Get-View cmdlets.

But you can still make some improvements. Some suggestions:

  • use the Filter parameter on the Get-View instead of the If statement
  • do the sort on the results
  • use the Property parameter on all the Get-View calls

$gvProps = "Name","Parent",
  "Runtime.Host",
  "Config.Annotation",
  "Config.GuestFullName",
  "Config.Hardware.MemoryMB",
  "Config.Hardware.NumCPU",
  "Config.Template",
  "Guest.IpAddress",
 
"Guest.Disk"

$Report
= @()
Get-View
-ViewType VirtualMachine -Property $gvProps -Filter @{"Config.Template"="False"} | %{     $row = "" | Select-Object Name,Notes,MemoryGB,Host,CPUs,OS,Cluster,Folder,IPAddress,DiskSpaceGB,UsedSpaceMB
   
$row.Host = Get-View $_.Runtime.Host -Property Name | Select -ExpandProperty Name
    $row.Folder = Get-View $_.Parent -Property Name | Select -ExpandProperty Name
    $row.Cluster = (Get-View (Get-View $_.Runtime.Host -Property Parent).Parent -Property Name).Name
    $row.Name = $_.Name
   
$Report += $row
}
$Report | Sort-Object -Property Name

I'm pretty sure Matt knows some other Get-View trickery to make it even faster Smiley Wink


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

jnewton20111014
Contributor
Contributor
Jump to solution

ZoOOM!!!!

Those changes net me a 53% increase in speed from my smaller vCenters and a 50% increase over all when ran across everything.  That's with almost 2000 VMs and 7 vCenters.

Also got me thinking to think of better ways to do my other scripts!  Thank you!!

0 Kudos
mattboren
Expert
Expert
Jump to solution

I'm pretty sure Matt knows some other Get-View trickery to make it even faster Smiley Wink

Lol, Luc.  Well, you pretty much have the Get-View tricks handled -- using -Filter instead of the If statement, and specifying -Property on each Get-View call.

The way to further speed this up is to get extra serious and break out the UpdateViewData() method and use the LinkedView properties on the managed objects, instead of the additional Get-View calls.  Yes, I am actually about to say this:  As sweet as Get-View is, there is a time to use something else.

So, for example, this could be futher speed-optimized like:

## removed a few properties from the list, as they will be handled differently with LinkedViews
$gvProps = "Name",
 
"Config.Annotation",
 
"Config.GuestFullName",
 
"Config.Hardware.MemoryMB",
 
"Config.Hardware.NumCPU",
 
"Config.Template",
 
"Guest.IpAddress",
 
"Guest.Disk"

Get-View -ViewType VirtualMachine -Property $gvProps -Filter @{"Config.Template"="False"} | %{
   
## get select properties for a few linked objects (so as not to have to do additional Get-View calls; Get-View is awesome, but even it comes at a cost)
    $_.UpdateViewData("Runtime.Host.Name","Parent.Name","Runtime.Host.Parent.Name")
   
New-Object -Type PSObject -Property @{
        Host
= $_.Runtime.LinkedView.Host.Name  ## use LinkedView instead of add'l Get-View calls
        Folder = $_.LinkedView.Parent.Name
        Cluster
= $_.Runtime.LinkedView.Host.LinkedView.Parent.Name
        Name
= $_.Name
    }
## end new-object
} | Sort-Object -Property Name

## ...leaving the other static items like Annotation and whatnot up to the consumer to add back in -- they did not involve additional Get-View calls

Notice the single Get-View call, and the use of the UpdateViewData() method.  In testing, the pretty-well-optimized, multiple Get-View version was bettered considerably by the UpdateViewData() version:

versionrun time (sec), 80 VMs
run time (sec), 465 VMs
using multiple Get-View calls25s404s
using UpdateViewData() and LinkedViews4s99s
improvement factor~6x~4x

There are different scenarios where this method saves even more run time.  I wrote about such goodness in my Even Faster PowerCLI Code with Get-View, UpdateViewData() and LinkedViews post at vNugglets.com a bit ago.  That post helps to explain the relationship of LinkedViews to the managed objects themselves.  If that post needs more info, someone please let us know.  And, yes, this somewhat highlights the "speed of code" versus "legibility/understandability of code" discussion, but, if the goal is just speed, speed, speed...

Anyway, how does that do for you, jnewton201110?

LucD
Leadership
Leadership
Jump to solution

Great stuff Matt, you're the Jedi Master of the Get-View force Heart


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

0 Kudos
esxi1979
Expert
Expert
Jump to solution

Is it possible at 1st place to use get-view in place of

Get-VM | Select-Object -Property Name,VMHost,@{N="Cluster";E={$_.VMHost.Parent}},Folder

?

I wanted to know with

Get-View -ViewType virtualmachine, is it possible to get the cluster info of the VM ?

0 Kudos
mattboren
Expert
Expert
Jump to solution

Hello, esxi1979-

Yes, it is possible, though, maybe not the most straightforward, to get the cluster info of the VM.  You could either do so with a couple of additional Get-View calls, or by using the UpdateViewData() method discussed earlier in this thread.  For example:

Get-View -ViewType VirtualMachine -Property Name | Select Name,
   
## use UpdateViewData() to populate the linked view, then access said linked view
    @{n="Cluster"; e={$_.UpdateViewData("Runtime.Host.Parent.Name"); $_.Runtime.LinkedView.Host.LinkedView.Parent.Name}}

Though, this highlights that there is a time and place for methods/techniques, and that this is not necessarily the time for UpdateViewData(), if speed is the objective.

An alternative would be to structure your query a bit differently:  use the -SearchRoot parameter to Get-View, and iterate through all of the clusters in your environment.  Something like:

## get the cluster View objects
Get-View -ViewType ClusterComputeResource -Property Name -PipelineVariable viewThisCluster | %{
   
## get the virtual machine View objects in this cluster
    Get-View -ViewType VirtualMachine -SearchRoot $viewThisCluster.MoRef -Property Name |
       
Select Name,@{n="Cluster"; e={$viewThisCluster.Name}}
}
## end foreach-object

Note:  this tidbit leverages the -PipelineVariable common parameter introduced in PowerShell v4.

Enjoy.

Message was edited by Matt Boren on 30 Nov 2014:  Ah, I see that this last question was double posted.  LucD (of course) provided an answer, too, at the other post at https://communities.vmware.com/message/2452857#2452857.

0 Kudos
georgebolo
Contributor
Contributor
Jump to solution

Hi Matt,

That's some excellent powercli optimizations. I have been working on a project: GitHub - gbolo/vSummary: A View into your VMware vSphere Environment

would you be able to look over my powercli script and make comments/suggestions? vSummary/vsummary_collect.ps1 at master · gbolo/vSummary · GitHub

Thanks!

0 Kudos
mattboren
Expert
Expert
Jump to solution

Hello, georgebolo-

Thanks, I appreciate the feedback.

As for reviewing the PowerCLI in vSummary -- surre, I would be able to.  In fact, I have now done so.

So that you could most easily digest the suggestions/comments, I forked your vSummary repo, and placed the resulting fork at https://github.com/mtboren/vSummary_ReviewFork.  The things that I changed:

  1. added a observationsAndReview-MattBoren.txt file at the root of the repo, containing most of the observations/comments
  2. added/updated code directly in the .\powershell\vsummary_collect.ps1 file

Reading the new text file is pretty straightfoward, and the commit diff view provides a great way to quickly pick out my additions/changes to the .ps1 file (just as is one of the points of version control).  The full link to that commit's diff view:

Enjoy the feedback, and let me know if you want to discuss anything.  If we do continue the discussion, we can probably use GitHub or <something else besides this PowerCLI forum thread, so as not to post a bunch of off-topic things in this thread>.

0 Kudos