VMware Cloud Community
meoli
Enthusiast
Enthusiast
Jump to solution

Get many Information about the virtual Machine Hardware (PS-Newbie wan't to learn)

Hey there Smiley Happy,

Introduction

i don't have many Experience with Powershell but want to learn it cause it is a great tool to get many Informations about VMs with the PowerCLI.

ToDo:

I want to create a PowerCLI-Code which gives me pretty much all the Information about a virtual machine Hardware

vCPUs

vRAM

NIC with MAC-Address and NIC-type

Disks with their DatastorePath and SCSI IDs

SCSI Controller with their IDs

Whats going on in my mind

I Have my VM "OL-LAB-DC-01"

where i can see from the vSphere Client the following Information:

1 vCPU,

2GB RAM

80GB ThinProvisioned Disk with the Datadsore Path on SCSI-Controller 0 and SCSI ID 0:0

SCSI-Controller 0 = LSI Logic SAS

NIC 3 is a VMXNET 3 NIC with Portgroup VM Network and the MAC-Adress XYZ

Thats the easy way but nobody would like to get this for each virtual Machine and thats why i need PowerCLI Smiley Happy

First Steps

So far i can get mostly everything with one specific command:

vCPUs: Get-VM OL-LAB-DC-01

vRAM: Get-VM OL-LAB-DC-01

NICs: Get-VM OL-LAB-DC-01 | Get-NetworkAdapter

Get-VM OL-LAB-DC-01 | Get-Harddisk

Get-VM OL-LAB-DC-01 | Get-ScsiController

Questions

Apart from CPU, Memory and the NICs there is Information which i'm missing Smiley Sad

How can i know that the vmdk is ThinProvisioned? I only get the output: Capacyity Persistence Filename?

How can i get the used SCSI IDs for the vmdks? And see on which SCSI ID (0) the SCSI-Controller is?

I Know that i can actually somehow use -ExpandProperty and select Propertys which aren't shown with the normal command (I used that from a code-snipplet to get VMs with their Appropriate Tag)- where do i find all those selectable Propertys?

The Second Question which i have is: found it Smiley Happy @{N='NAME';E={(Get-whatiwant $_).Object}}

How can i get a one-liner out of that so that in the End it prints me out a Table where i have everything next to each other? Just Piping it trough will end in giving me errors because the pipe will refer to the command used before piping...

Thx for reading!

It's not like i wanna be a freeloader and get the Code-Snipplet because i'm lazy Smiley Wink Rather than that I would like to try it myself but i need answers for my Questions Smiley Happy

Best regards!

:Edit:

So far i have this massive one-liner which will get definitely longer...:

Get-VM ol-lab-dc-01 | Select-Object Name,NumCPU,MemoryGB,@{N='NIC-Name';E={(Get-NetworkAdapter $_).Name}},@{N='Portgruppe';E={(Get-NetworkAdapter $_).NetworkName}},@{N='Type';E={(Get-NetworkAdapter $_).Type}},@{N='MAC-Adresse';E={(Get-NetworkAdapter $_).MacAddress}},@{N='vmdk';E={(Get-HardDisk $_).DiskType}}

1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

It's a matter of doing a number of nested ForEach loops.

$vmNames = 'mars','venus','jupiter'

 

$report = foreach($vm in (Get-View -ViewType VirtualMachine -Filter @{'Name' = "$($vmNames -join '|')"})){

    foreach($ctrl in ($vm.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualScsiController]})){

        foreach($disk in ($vm.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualDisk] -and $_.ControllerKey -eq $ctrl.Key})){

            $obj = [ordered]@{

                SCSIController = $ctrl.DeviceInfo.Label

                DiskName = $disk.DeviceInfo.Label 

                SCSI_Id = "$($ctrl.BusNumber) : $($disk.UnitNumber)" 

                DiskFile = $disk.Backing.FileName 

                DiskSize = $disk.CapacityInKB * 1KB / 1GB 

                VName = $vm.Config.Name

                VCPU = $vm.Config.Hardware.NumCPU 

                VMemory = $vm.Config.Hardware.MemoryMB 

                VNIC = $vm.config.hardware.Device.DeviceInfo | where {$_.Label -match "Network "} | select -ExpandProperty Label 

                VMAC = $vm.Config.Hardware.Device.MACAddress 

                VPG = $vm.Config.Hardware.Device.DeviceInfo | where {$_.Label -match "Network"} | select -Expandproperty Summary

            }

            New-Object PSObject -Property $obj

        }

    }

}

$report | Export-Csv report.csv -NoTypeInformation -UseCulture


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

View solution in original post

9 Replies
jpsider
Expert
Expert
Jump to solution

I would start with something like this using get-view (not get-vm)

$vm = get-view -ViewType VirtualMachine -filter @{"Name"="VM"}

Then you can start playing with the related items

$vm.config

$vm.config.hardware

Here is a great getting started article : Get-View Part 1: Introduction to Get-View - VMware PowerCLI Blog - VMware Blogs

0 Kudos
LucD
Leadership
Leadership
Jump to solution

If you want to combine objects returned by multiple cmdlets in a one-liner, you will need to use a pipeline variable and calculated properties.

Something like this for example:

Get-VM -PipelineVariable vm |

Get-NetworkAdapter |

select @{N='VM';E={$vm.Name}},

    @{N='NumCPU';E={$vm.NumCPU}},

    @{N='MemoryGB';E={$vm.MemoryGB}},

    Name,Type,NetworkName,MacAddress

The Select will work on the object returned by the Get-NetworkAdapter cmdlet, and via the $vm pipelinevariable you will also have access to the object returned by Get-VM.

The properties from that last object are retrieved through what is called calculated properties.

Update: I would not advise you to use Get-View when you are still in the beginners phase.
That cmdlet returns another type of object, and is more for an intermediate or advanced phase.


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

0 Kudos
meoli
Enthusiast
Enthusiast
Jump to solution

Thx for your answer!

The Example of how to join different cmdlets really helped me out!

But i can't find anything to get the SCSI IDs of the Controller and the Disks Smiley Sad+

And many different Scripts which i found won't give me any results:

VMware PowerCLI script to get VM’s virtual and RDM disk information | vStrong.info

https://github.com/CoteRL/VMware-PowerCLI/blob/master/Get-VMDisk.ps1

I tried to lookup the code but i can't even find "DeviceInfo.label" in the Get View .Config.Hardware.Device View...

But i think i found the virutal disk itself with the Get-View command:

$vm.Config.Hardware.Device (Get-View is stored in $vm)

CapacityInKB          : 20971520

CapacityInBytes       : 21474836480

Shares                : VMware.Vim.SharesInfo

StorageIOAllocation   : VMware.Vim.StorageIOAllocationInfo

DiskObjectId          : 60-2000

VFlashCacheConfigInfo :

Iofilter              :

VDiskId               :

Key                   : 2000

DeviceInfo            : VMware.Vim.Description

Backing               : VMware.Vim.VirtualDiskFlatVer2BackingInfo

Connectable           :

SlotInfo              :

ControllerKey         : 1000

UnitNumber            : 0

But i only assume this since there is atleast a capacity shown there. but the other Information seem to me to be useless? Like what does the Controller Key mean and is the UnitNumber my SCSI-ID for the Disk itself?

Regards!

0 Kudos
LucD
Leadership
Leadership
Jump to solution

I didn't include any disk info, since I'm not sure how you would incorporate VM, NIC and vDisk information on the same line.

Think of multiple NICs and/or multiple vDisks for a VM.

This would produce a rather large amount of lines, but including properties that have no relation to each other.

VM,NIC1,Disk1

VM,NIC1,Disk2

...

One option is to first calculate the maximum NICs and vDisks are present for the VMs.

Then generate that number of columns for each row, but leave the columns blank is needed.

For example:

VM,NIC1,NIC2,NIC,Disk1,Disk2,Disk3,Disk4


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

0 Kudos
meoli
Enthusiast
Enthusiast
Jump to solution

well so far and with some help of other code-snipplets i have this code running

#$VISSERVER = Read-Host -Prompt 'Input your vCenter Server Name or IP-Adress'

#Connect-VIServer $VISERVER

#$Vm = Read-Host "Enter VMName"

$Vm = 'mars'

#Create the array for all the Information

$DiskInfo= @()

#Create the $vmview Variable for easy use while referring to the $VM-Variable (Get Infos from 1 Virtual Machine)

$VmView = Get-View -ViewType VirtualMachine -Filter @{"Name" = $VM}

#Create the $vmview Variable for all Virtual Machines in the vCenter

#VmView = Get-View -ViewType Virtualmachine

#Do a Loop and give me all those Informations

  foreach ($VirtualSCSIController in ($VMView.Config.Hardware.Device | where {$_.DeviceInfo.Label -match "SCSI Controller"})) {

  foreach ($VirtualDiskDevice in ($VMView.Config.Hardware.Device | where {$_.ControllerKey -eq $VirtualSCSIController.Key})) {

  $VirtualDisk = "" | Select SCSIController, DiskName, SCSI_Id, DiskFile, DiskSize,VName,VCPU,VMemory,VNIC,VMAC,VPG

  $VirtualDisk.SCSIController = $VirtualSCSIController.DeviceInfo.Label

  $VirtualDisk.DiskName = $VirtualDiskDevice.DeviceInfo.Label

  $VirtualDisk.SCSI_Id = "$($VirtualSCSIController.BusNumber) : $($VirtualDiskDevice.UnitNumber)"

  $VirtualDisk.DiskFile = $VirtualDiskDevice.Backing.FileName

  $VirtualDisk.DiskSize = $VirtualDiskDevice.CapacityInKB * 1KB / 1GB

                $VirtualDisk.VName = $VMview.Config.Name

                $VirtualDisk.VCPU = $VMview.Config.Hardware.NumCPU

                $VirtualDisk.VMemory = $VmView.Config.Hardware.MemoryMB

                $VirtualDisk.VNIC = $VMview.config.hardware.Device.DeviceInfo | where {$_.Label -match "Network "} | select -ExpandProperty Label

                $VirtualDisk.VMAC = $VMview.Config.Hardware.Device.MACAddress

                $VirtualDisk.VPG = $VMView.Config.Hardware.Device.DeviceInfo | where {$_.Label -match "Network"} | select -Expandproperty Summary

  $DiskInfo += $VirtualDisk

}

}

#Export the Results of the array

$DiskInfo | export-csv -Path C:\Users\ol\Documents\_stuff\test.csv

This works fine when i just want the Information for 1 Virtual Machine - of course when a VM has more than 1 NIC it doesn't look that nice but thats not the big problem... (see Diskinfo-singlevm.png)

When i use "vmview = Get-View -viewType Virtualmachine" the Rows gets filled with too much information (check Diskinfo-allvms.png)

I tried to seperate both information into 2 Arrays but i couldn't put them together

So far i can only think of two ways:

1. Create a new Array just for the VM-Names and create a big loop where $VM is getting the new VM-Name out of the Array then get all Informations and after that export it into a single csv-file or append it to a existing csv-file and start with the next VM in the "Name-Array" untill the whole loop is finished

2. Get the script working without calling a single VM out...

I think the first way is in my range of knowledge (as long as i can merge export-csv into a single file together)

Are there better ways which i totally oversee?

regards

0 Kudos
LucD
Leadership
Leadership
Jump to solution

It's a matter of doing a number of nested ForEach loops.

$vmNames = 'mars','venus','jupiter'

 

$report = foreach($vm in (Get-View -ViewType VirtualMachine -Filter @{'Name' = "$($vmNames -join '|')"})){

    foreach($ctrl in ($vm.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualScsiController]})){

        foreach($disk in ($vm.Config.Hardware.Device | where{$_ -is [VMware.Vim.VirtualDisk] -and $_.ControllerKey -eq $ctrl.Key})){

            $obj = [ordered]@{

                SCSIController = $ctrl.DeviceInfo.Label

                DiskName = $disk.DeviceInfo.Label 

                SCSI_Id = "$($ctrl.BusNumber) : $($disk.UnitNumber)" 

                DiskFile = $disk.Backing.FileName 

                DiskSize = $disk.CapacityInKB * 1KB / 1GB 

                VName = $vm.Config.Name

                VCPU = $vm.Config.Hardware.NumCPU 

                VMemory = $vm.Config.Hardware.MemoryMB 

                VNIC = $vm.config.hardware.Device.DeviceInfo | where {$_.Label -match "Network "} | select -ExpandProperty Label 

                VMAC = $vm.Config.Hardware.Device.MACAddress 

                VPG = $vm.Config.Hardware.Device.DeviceInfo | where {$_.Label -match "Network"} | select -Expandproperty Summary

            }

            New-Object PSObject -Property $obj

        }

    }

}

$report | Export-Csv report.csv -NoTypeInformation -UseCulture


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

meoli
Enthusiast
Enthusiast
Jump to solution

Thx! that really helped me a lot!

And if you don't wanna hardcode the VM-names you can use the following 3-liner as a little help Smiley Wink

Get-VM | select -Expandproperty Name | out-file C:\Users\ol\Documents\_stuff\input.txt

$Lines = Get-Content C:\Users\ol\Documents\_stuff\input.txt

$vmNames = $lines

maybe this can be shortened into a one-liner  - but this worked for me Smiley Happy

But ofcourse a new problem appears...

I do know that some VMs have multiple NICs and stuff which is ok. WHen i use $Report | out-gridview i could live with how it is shown. But unfortunately something goes wrong when i export the $report to a csv because the lines with Multiple Entris (vNIC, MAC, Portgroups) are getting replaced by System.Object[]

Just need to look this up and then i'm done Smiley Happy

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Yes, Export-Csv doesn't know how to fit the array (multiple values) into a single cell.

A quick and dirty fix for this is to transform the array into a single string.

That can be done with the -join operator

VNIC = ($vm.config.hardware.Device.DeviceInfo | where {$_.Label -match "Network "} | select -ExpandProperty Label) -join ','


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

meoli
Enthusiast
Enthusiast
Jump to solution

Thx LucD!

i tried the join but i made a mistake because i didn't knew where i had to place the () and googling showed me other

really helped me out and with all those information it helped myself understanding powershell and powercli really good!

Regards!

0 Kudos