VMware Cloud Community
D0minic
Contributor
Contributor
Jump to solution

Get-View -ViewType VirtualMachine, doesn't get all needed values

Hello,

Unfortunately I cannot figure out how to extract some data from a VM. I want to extra info and export to a json file. The code I'm using isn't given me the right depth to the "ConvertTo-Json". It seems like it's only limited to 4 layers of depth. After the fourth layer it seems no new info is added to the file.

Example code:

$vm = Get-View -ViewType VirtualMachine  | select *

$json = $vm | Select -First 1 | ConvertTo-Json -Depth 5

I'm trying to get the contents of the fields below:

Config.Uuid]

[Config.Hardware.Device.Key]

[Config.Hardware.Device.CapacityInBytes]

[Config.Hardware.Device.CapacityInKB]

[Config.Hardware.Device.DiskObjectId]

[Config.Hardware.Device.DeviceInfo]

[Config.Hardware.Device.ThinProvisioned]

[Config.Hardware.Device.Backing.Datastore.Value]

Note:

When I use C# (through the API) I get the correct depth and information I'm looking for. How can I accomplish the same with Powershell?

Any help is greatly appreciated!

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

The 1st problem is your Select * on the first line, that one is not needed.
And in fact a Select-Object produces another object than the VirtualMachine object you would expect.

If you leave that out you will encounter the infamous "an item with the same key has already been added".

One way to bypass this is to deserialise the VirtualMachine object before passing it to the ConvertTo-Json cmdlet.

See for example Deserializing Large JSON Payloads into a PowerShell Hashtable

A better solution in my opinion is to look at the cause of the error.

JSON has a convention to represent data as a Key-Pair, unfortunately vSphere objects contain properties with the same name.

In different locations, but still a problem for the ConvertTo-Json cmdlet.

I find selecting the data you want explicitly and making sure the your hash table contains no duplicate keys.

Something like this for example (note that I only included some of the properties you want).

Get-View -ViewType VirtualMachine -Property 'Name', 'Config.Uuid', 'Config.Hardware' |

   ForEach-Object -Process {

   $vm = $_

   $vm.Config.Hardware.Device |

   ForEach-Object -Process {

   New-Object PSObject -Property @{

   Name = $vm.Name

   Uuid = $vm.Config.Uuid

   Device = $_.DeviceInfo.Label

   }

   }

} | ConvertTo-Json


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

View solution in original post

Reply
0 Kudos
5 Replies
LucD
Leadership
Leadership
Jump to solution

The 1st problem is your Select * on the first line, that one is not needed.
And in fact a Select-Object produces another object than the VirtualMachine object you would expect.

If you leave that out you will encounter the infamous "an item with the same key has already been added".

One way to bypass this is to deserialise the VirtualMachine object before passing it to the ConvertTo-Json cmdlet.

See for example Deserializing Large JSON Payloads into a PowerShell Hashtable

A better solution in my opinion is to look at the cause of the error.

JSON has a convention to represent data as a Key-Pair, unfortunately vSphere objects contain properties with the same name.

In different locations, but still a problem for the ConvertTo-Json cmdlet.

I find selecting the data you want explicitly and making sure the your hash table contains no duplicate keys.

Something like this for example (note that I only included some of the properties you want).

Get-View -ViewType VirtualMachine -Property 'Name', 'Config.Uuid', 'Config.Hardware' |

   ForEach-Object -Process {

   $vm = $_

   $vm.Config.Hardware.Device |

   ForEach-Object -Process {

   New-Object PSObject -Property @{

   Name = $vm.Name

   Uuid = $vm.Config.Uuid

   Device = $_.DeviceInfo.Label

   }

   }

} | ConvertTo-Json


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

Reply
0 Kudos
D0minic
Contributor
Contributor
Jump to solution

I was still having problems with the ConvertTo-Json because of the different depths levels. I made a succesful workaround by creating an own object and filled it with the property method you provided. Thanks for your help!

            $vms2 = Get-View -ViewType VirtualMachine -Property 'Config.Hardware.Device','Config.Uuid'                            

            $devices = @()                

               foreach ($vm in $vms2) {                   

                    $device = New-Object PSObject                    

                   

                    Add-Member -InputObject $device -MemberType NoteProperty -Name 'Uuid' -Value   $vm.Config.Uuid                    

                    Add-Member -InputObject $device -MemberType NoteProperty -Name 'MoRef' -Value   $vm.MoRef                    

                    Add-Member -InputObject $device -MemberType NoteProperty -Name 'Config.Hardware.Device' -Value $vm.Config.Hardware.Device                    

                    Add-Member -InputObject $device -MemberType NoteProperty -Name 'CustomerEnvironment_NK' -Value $vCenterCustomerEnvironment                    

                    Add-Member -InputObject $device -MemberType NoteProperty -Name 'ExtractSource' -Value $vCenterName                    

                    Add-Member -InputObject $device -MemberType NoteProperty -Name 'ExtractTimestamp' -Value $ExtractTimestamp                    

                    $devices += $device                

                    }

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

But you are again trying pass objects vs singular values to the entries in that object.
Which properties do you actually need in your resulting report?
The easiest solution to avoid any issues is to go for singular values, the the ConvertTo-Json will not have any issues with Depth nor with "duplicate keys".


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

Reply
0 Kudos
D0minic
Contributor
Contributor
Jump to solution

Our preference is to store the whole object. We are capturing this data in a datalake in order to further analyze this.

We know what information requirements we have today, which is why I focussed on the mentioned properties. By capturing whole objects though (or as complete as possible) I make sure that I can answer future questions which might require additional properties just as well... and have a history of the properties available Smiley Happy

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

I'm afraid there is simply not valid solution if you want to export the full object to JSON.

You're hitting a JSON syntax limitation (at least that is what most seem to acknowledge).
See here for an example of the duplicate key discussion


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