9 Replies Latest reply on Sep 23, 2015 6:03 PM by mattboren

    get-view

    tdubb123 Master

      Can someone please explain this

       

       

      $vmname = get-vm vm

       

      get-view -id $vmname.id

       

      --------------------------------------------------------------------------------------------------------------------------

       

      Capability           : VMware.Vim.VirtualMachineCapability

      Config               : VMware.Vim.VirtualMachineConfigInfo

      Layout               : VMware.Vim.VirtualMachineFileLayout

      LayoutEx             : VMware.Vim.VirtualMachineFileLayoutEx

      Storage              : VMware.Vim.VirtualMachineStorageInfo

      EnvironmentBrowser   : EnvironmentBrowser-envbrowser-56698

      ResourcePool         : ResourcePool-resgroup-56694

      ParentVApp           :

      ResourceConfig       : VMware.Vim.ResourceConfigSpec

      Runtime              : VMware.Vim.VirtualMachineRuntimeInfo

      Guest                : VMware.Vim.GuestInfo

      Summary              : VMware.Vim.VirtualMachineSummary

      Datastore            : {Datastore-datastore-56696}

      Network              : {Network-network-386}

      Snapshot             :

      RootSnapshot         : {}

      GuestHeartbeatStatus : gray

      LinkedView           :

      Parent               : Folder-group-v395

      CustomValue          : {}

      OverallStatus        : green

      ConfigStatus         : green

      ConfigIssue          : {}

      EffectiveRole        : {-1}

      Permission           : {}

      Name                 : aus-test

      DisabledMethod       : {MakePrimaryVM_Task, TerminateFaultTolerantVM_Task, RevertToCurrentSnapshot_Task,

                             RemoveAllSnapshots_Task...}

      RecentTask           : {}

      DeclaredAlarmState   : {alarm-10.vm-56698, alarm-11.vm-56698, alarm-2.vm-56698, alarm-23.vm-56698...}

      TriggeredAlarmState  : {}

      AlarmActionsEnabled  : True

      Tag                  : {}

      Value                : {}

      AvailableField       : {}

      MoRef                : VirtualMachine-vm-56698

      Client               : VMware.Vim.VimClientImpl

       

      -----------------------------------------------------------------------------------------------------------------------------------

       

      but

       

      get-view -viewtype virtualmachine -filter @{"name" = $vmname}

       

      PS C:\Users\tkw\scripts> get-view -ViewType virtualmachine -filter @{"name" =  $vmname}

      get-view : 9/20/2015 9:00:13 AM    Get-View        Invalid object specified for the Filter parameter  - 'Hashtable{String,

      VirtualMachineImpl}'. Filter accepts objects of type  'Hashtable{String, String}'.  

      At line:1 char:1

      + get-view -ViewType virtualmachine -filter @{"name" =  $vmname}

      + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

          + CategoryInfo          : InvalidArgument: (System.Collections.Hashtable:Hashtable) [Get-View], VimException

          + FullyQualifiedErrorId : Core_GetVIView_TryGetFilterParam_InvalidValue,VMware.VimAutomation.ViCore.Cmdlets.Commands.Do

         tNetInterop.GetVIView

       

       

      any idea?

        • 1. Re: get-view
          tdubb123 Master

          ok what is the difference here?

           

           

           

          get-view -viewtype virtualmachine -filter @{"name" = "$vmname"}

           

          and

           

          get-view -id $vmname.id

          • 2. Re: get-view
            mattboren Master
            vExpert

            Hello, tdubb123-

             

            The issue is with the value that you are providing for the "Name" key in the -Filter hashtable in the Get-View call -- the value should be a string, but you are using a VirtualMachineImpl object.  The error that you are getting:

            Invalid object specified for the Filter parameter  - 'Hashtable{String,VirtualMachineImpl}'. Filter accepts objects of type  'Hashtable{String, String}'

             

            tries to point that out.  That is to say, $vmname is not a String -- it is the entire VirtualMachineImpl object returned from Get-VM.  So, to use that variable in the Filter in the Get-View call, you would need to access the .Name property of the variable.  Like:

             

            Get-View -ViewType VirtualMachine -Filter @{"Name" = $vmname.Name}

             

            And, maybe to help avoid such confusion, naming that variable "$vm" or the likes would be better, since the contents of the variable are not just the VM's name, but the whole VM object.

             

            That work for you?

            • 3. Re: get-view
              mattboren Master
              vExpert

              Hello-

               

              Here you got around the "supplying a VirtualMachineImpl as the value to the Name key in the Get-View Filter" by getting the String value of $vmname.  Again, $vmname in your example is a VirtualMachineImpl object.  So, if you look at the contents of that variable, you should see a full virtual machine object, like:

              Name  PowerState Num CPUs MemoryGB
              ----  ---------- -------- --------
              myVM0 PoweredOff 1        1.000

               

              But, by adding quotes around the variable, you are creating a string, and the .ToString() method of the $vmname variable is invoked, which results in just the String value that is the name of the VM.  That set of quotes around $vmname in the Filter hashtable is the difference between this post and your original post, and the reason why both of your examples in this "what is the difference here" post work.

               

              As for what is the difference:

              • the first example is getting VirtualMachine objects whose name matches the given value in the Filter
              • the second example uses the ID of the VirtualMachineImpl object (which corresponds to the MoRef of the managed object) to get the VirtualMachine object

               

              Another difference:  the first example might get more than one VirtualMachine object, whereas the second example should get exactly one VirtualMachine object (assuming that you are connected to only one vCenter, and that a VirtualMachine with that ID still exists).

               

              The reason that the first example might return multiple VirtualMachine objects is that the filter is using regular expression matching on the name pattern that you supplied as a value to the "Name" key.  So, the regular expression of "myVM0" matches, of course, "myVM0", but also matches "myVM01", "myVM0_old", "do_not_use_this_vm_myVM0", and so on.

               

              Make sense?

              • 4. Re: get-view
                tdubb123 Master

                Hi Matt

                 

                Thanks for your detailed explanation. It does makes sense. 

                 

                I have another example.

                 

                $vms = get-cluster AUS | get-vm

                 

                output gives this

                 

                PS C:\Users\tkw\scripts> get-cluster AUS | get-vm

                 

                 

                Name                 PowerState Num CPUs MemoryGB      

                ----                 ---------- -------- --------      

                aus-dc (2)           PoweredOn  1        4.000         

                aus-dfs (2)          PoweredOn  2        4.000         

                aus-w7               PoweredOn  1        2.000         

                astris2 (2)          PoweredOn  2        3.996         

                aus-svcs (2)         PoweredOn  1        4.000         

                aus-test             PoweredOn  2        4.000

                 

                ----------------------------------------------------------------------------------------------

                 

                but

                foreach ($vmname in $vms) {

                get-view -viewtype virtualmachine -filter @{"name" = $vmname.name

                }

                 

                 

                gives only output of 2 vms

                 

                Capability           : VMware.Vim.VirtualMachineCapability

                Config               : VMware.Vim.VirtualMachineConfigInfo

                Layout               : VMware.Vim.VirtualMachineFileLayout

                LayoutEx             : VMware.Vim.VirtualMachineFileLayoutEx

                Storage              : VMware.Vim.VirtualMachineStorageInfo

                EnvironmentBrowser   : EnvironmentBrowser-envbrowser-56705

                ResourcePool         : ResourcePool-resgroup-56694

                ParentVApp           :

                ResourceConfig       : VMware.Vim.ResourceConfigSpec

                Runtime              : VMware.Vim.VirtualMachineRuntimeInfo

                Guest                : VMware.Vim.GuestInfo

                Summary              : VMware.Vim.VirtualMachineSummary

                Datastore            : {Datastore-datastore-56696}

                Network              : {Network-network-386}

                Snapshot             :

                RootSnapshot         : {}

                GuestHeartbeatStatus : green

                LinkedView           :

                Parent               : Folder-group-v395

                CustomValue          : {}

                OverallStatus        : green

                ConfigStatus         : green

                ConfigIssue          : {}

                EffectiveRole        : {-1}

                Permission           : {}

                Name                 : aus-w7

                DisabledMethod       : {Destroy_Task, UnregisterVM, RevertToCurrentSnapshot_Task, RemoveAllSnapshots_Task...}

                RecentTask           : {Task-task-132122}

                DeclaredAlarmState   : {alarm-10.vm-56705, alarm-11.vm-56705, alarm-2.vm-56705, alarm-23.vm-56705...}

                TriggeredAlarmState  : {}

                AlarmActionsEnabled  : True

                Tag                  : {}

                Value                : {}

                AvailableField       : {}

                MoRef                : VirtualMachine-vm-56705

                Client               : VMware.Vim.VimClientImpl

                 

                 

                Capability           : VMware.Vim.VirtualMachineCapability

                Config               : VMware.Vim.VirtualMachineConfigInfo

                Layout               : VMware.Vim.VirtualMachineFileLayout

                LayoutEx             : VMware.Vim.VirtualMachineFileLayoutEx

                Storage              : VMware.Vim.VirtualMachineStorageInfo

                EnvironmentBrowser   : EnvironmentBrowser-envbrowser-56698

                ResourcePool         : ResourcePool-resgroup-56694

                ParentVApp           :

                ResourceConfig       : VMware.Vim.ResourceConfigSpec

                Runtime              : VMware.Vim.VirtualMachineRuntimeInfo

                Guest                : VMware.Vim.GuestInfo

                Summary              : VMware.Vim.VirtualMachineSummary

                Datastore            : {Datastore-datastore-56696}

                Network              : {Network-network-386}

                Snapshot             :

                RootSnapshot         : {}

                GuestHeartbeatStatus : green

                LinkedView           :

                Parent               : Folder-group-v395

                CustomValue          : {}

                OverallStatus        : green

                ConfigStatus         : green

                ConfigIssue          : {}

                EffectiveRole        : {-1}

                Permission           : {}

                Name                 : aus-test

                DisabledMethod       : {Destroy_Task, UnregisterVM, RevertToCurrentSnapshot_Task, RemoveAllSnapshots_Task...}

                RecentTask           : {Task-task-132120}

                DeclaredAlarmState   : {alarm-10.vm-56698, alarm-11.vm-56698, alarm-2.vm-56698, alarm-23.vm-56698...}

                TriggeredAlarmState  : {}

                AlarmActionsEnabled  : True

                Tag                  : {}

                Value                : {}

                AvailableField       : {}

                MoRef                : VirtualMachine-vm-56698

                Client               : VMware.Vim.VimClientImpl

                 

                 

                any idea why?

                 

                whereas if I used

                 

                get-view -id $vmname.id

                 

                it gives output of all 6 vms. is this because of the  the "-filter" switch?

                • 5. Re: get-view
                  tdubb123 Master

                  can you help with this?

                   

                   

                  $vms = get-cluster $cluster | get-vm

                   

                  $vms | % {

                   

                  $vmname = $_.name

                  $vmview = get-view -id $vmname

                   

                   

                   

                  how do I get a get-view of these  vms ?

                  • 6. Re: get-view
                    mattboren Master
                    vExpert

                    Hello-

                     

                    Good.

                     

                    As for why using -Filter for Name only returns four of those six VMs:  this is because of the fact that the value for the Name key is a regular expression pattern, and that some of your VMs have characters that mean something different in the context of a regular expression.  Specifically, the parenthesis are grouping construct characters in the regular expression context.  You can read about such things at MSDN Regular Expression Reference.

                     

                    You can see the behavior in the example:

                    PS C:\> "aus-dc (2)" -match "aus-dc (2)"
                    False

                     

                    So, if you wanted to actually match by name, then you could escape those special characters in the string manually, or use the Escape() static method of the System.Text.RegularExpressions.Regex .NET class.  The behavior is then probably more like what you are expecting:

                    PS C:\> "aus-dc (2)" -match [Regex]::Escape("aus-dc (2)")
                    True

                     

                    Adding the [Regex]::Escape() in the Filter like "...-Filter @{'Name' = [Regex]::Escape($vmname.name)}" would get closer to the behavior that you are expecting (but, again, the regular expression that you are using may match longer strings that contain the pattern that you are specifying).

                     

                    There are other, more precise ways to get the View objects.  I'll reply to your latest post here with more info on that.

                    • 7. Re: get-view
                      mattboren Master
                      vExpert

                      Hello, tdubb123-

                       

                      Sure.  While you could use a Foreach-Object scriptblock to call Get-View for every VM in the cluster, since everyone likes faster things, you can use just one Get-View call.  Like:

                       

                      ## get the VMs in the given cluster, put them in a variable, then get the Views
                      $vms = Get-Cluster $cluster | Get-VM
                      Get-View -Id $vms.Id

                       

                      And, you don't really need to store the VirtualMachineImpl objects from Get-VM in a variable -- you can just get their ID properties and use those directly for Get-View, like:

                       

                      ## just get the Views of the IDs of the VMs in the given cluster
                      Get-View -Id (Get-Cluster $cluster | Get-VM).Id

                       

                      But, since speed is often of concern, especially as the virtual inventory is larger, getting away from the Get-VM call altogether will be of great value.  Get-View has a -SearchRoot parameter that allows you to specify the inventory location to use as the root of the search, like:

                       

                      ## get the VirtualMachine Views at the given search root
                      Get-View -ViewType VirtualMachine -SearchRoot (Get-Cluster $cluster).Id

                       

                      And, to keep things efficient, since you likely will only want to use a few choice properties of the VirtualMachine View objects, you can further speed things along by specifying just those properties that you want to retrieve from the vCenter server, keeping memory usage in your PowerShell session lower, too.  Like:

                       

                      ## get the VirtualMachine Views at the given search root, retrieving just the select few properties
                      Get-View -ViewType VirtualMachine -Property Name, Config.Hardware -SearchRoot (Get-Cluster $cluster).Id

                       

                      A bit more involved to write, so you might chose the first couple of examples when issuing the commands interactively.  But, if you are writing a script where you care more about the run duration, or have a huge environment (or both), the last example is the winner.

                       

                      How does those do for you?

                      • 8. Re: get-view
                        tdubb123 Master

                        Hi Matt

                         

                        makes sense. thanks. great explanation. very much appreciated.

                         

                        is there a difference here

                         

                         

                        $vms = get-cluster | get-pvm

                         

                        $vms | %{

                         

                         

                        or

                         

                        foreach ($vm in $vms) {

                         

                        thanks

                        • 9. Re: get-view
                          mattboren Master
                          vExpert

                          Hello, tdubb123-

                           

                          Great, glad to hear it.

                           

                          As for the difference:  the first way is using the Foreach-Object cmdlet (its alias, "%"), whereas the second uses the PowerShell foreach loop.  While you can achieve similar (the same?) things with each construct, they do differ in things like efficiency and speed, and in the way that they emit objects.  The Foreach-Object cmdlet will place resulting objects on the pipeline for further consumption, whereas the foreach statement does not.

                           

                          Boe Prox made an informative post on the Hey, Scripting Guy! Blog:  Getting to Know ForEach and ForEach-Object.  That gets into the topics of speed, pipeline, and more.  Give that a look see for some deeper info on the topic.