11 Replies Latest reply on Jun 3, 2016 7:06 PM by mattboren

    Folder a VM is in using Get-View

    jnewton201110141 Lurker

      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?

        • 1. Re: Folder a VM is in using Get-View
          LucD Guru
          vExpertUser ModeratorsCommunity Warriors

          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: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
          • 2. Re: Folder a VM is in using Get-View
            jnewton201110141 Lurker

            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?

            • 3. Re: Folder a VM is in using Get-View
              RvdNieuwendijk Virtuoso
              vExpertUser Moderators

              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

              • 4. Re: Folder a VM is in using Get-View
                LucD Guru
                User ModeratorsvExpertCommunity Warriors

                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

                Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                1 person found this helpful
                • 5. Re: Folder a VM is in using Get-View
                  jnewton201110141 Lurker

                  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!!

                  • 6. Re: Folder a VM is in using Get-View
                    mattboren Master
                    vExpert

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

                     

                    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?

                    1 person found this helpful
                    • 7. Re: Folder a VM is in using Get-View
                      LucD Guru
                      vExpertUser ModeratorsCommunity Warriors

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

                      Blog: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                      • 8. Re: Folder a VM is in using Get-View
                        esxi1979 Hot Shot

                        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 ?

                        • 9. Re: Folder a VM is in using Get-View
                          mattboren Master
                          vExpert

                          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.

                          • 10. Re: Folder a VM is in using Get-View
                            georgebolo Lurker

                            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!

                            • 11. Re: Folder a VM is in using Get-View
                              mattboren Master
                              vExpert

                              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>.