VMware Cloud Community
tdubb123
Expert
Expert
Jump to solution

get-view

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?

Reply
0 Kudos
1 Solution

Accepted Solutions
mattboren
Expert
Expert
Jump to solution

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?

View solution in original post

Reply
0 Kudos
9 Replies
tdubb123
Expert
Expert
Jump to solution

ok what is the difference here?

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

and

get-view -id $vmname.id

Reply
0 Kudos
mattboren
Expert
Expert
Jump to solution

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?

Reply
0 Kudos
mattboren
Expert
Expert
Jump to solution

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?

Reply
0 Kudos
tdubb123
Expert
Expert
Jump to solution

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?

Reply
0 Kudos
tdubb123
Expert
Expert
Jump to solution

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 ?

Reply
0 Kudos
mattboren
Expert
Expert
Jump to solution

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.

Reply
0 Kudos
mattboren
Expert
Expert
Jump to solution

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?

Reply
0 Kudos
tdubb123
Expert
Expert
Jump to solution

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

Reply
0 Kudos
mattboren
Expert
Expert
Jump to solution

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.

Reply
0 Kudos