VMware Cloud Community
SkagnolaII
Contributor
Contributor
Jump to solution

Pull VM Inventory Specifying The Cluster

Hello!

I noticed this thread about pulling VM inventory from ESXi hosts: VMware PowerCLI Forum - VMware {code}

How would I go about modifying this to be a function and specifying the cluster?

i.e.

function Get-Inventory ($args1) {

     Get-Cluster "$args1" | Get-VM | etc. etc. ...

}

My PowerCLI version info below

PowerCLI Version

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

   VMware PowerCLI 11.2.0 build 12483598

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

Component Versions

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

   VMware Cis Core PowerCLI Component PowerCLI Component 11.2 build 12483642

   VMware VimAutomation VICore Commands PowerCLI Component PowerCLI Component 11.2 build 12483638

   VMware VimAutomation Srm PowerCLI Component PowerCLI Component 11.2 build 12483605

   VMware VimAutomation License PowerCLI Component PowerCLI Component 10.0 build 7893904

   VMware VimAutomation Vds Commands PowerCLI Component PowerCLI Component 11.2 build 12483615

   VMware Vmc PowerCLI Component PowerCLI Component 11.2 build 12483614

   VMware Nsxt PowerCLI Component PowerCLI Component 11.2 build 12483633

   VMware VimAutomation vROps PowerCLI Component PowerCLI Component 10.0 build 7893921

   VMware HorizonView PowerCLI Component 7.1.0 build 12680098

   VMware VimAutomation Cloud PowerCLI Component PowerCLI Component 11.0 build 10379994

   VMWare ImageBuilder PowerCLI Component 6.7 build 11233116

   VMWare AutoDeploy PowerCLI Component 6.7 build 11233116

   VMware VimAutomation Storage PowerCLI Component PowerCLI Component 11.2 build 12483611

   VMware vSphere Update Manager PowerCLI 6.5 build 7862888

   VMware VimAutomation Security PowerCLI Component PowerCLI Component 11.0 build 10380515

   VMware Hcx PowerCLI Component PowerCLI Component 11.2 build 12483619

Tags (1)
Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Leave out the ForEach loop over all the disks.

Replace

$vm.Config.Hardware.Device | where {$_.GetType().Name -eq "VirtualDisk"} |

    Select @{N="VM";E={$vm.Name}},

with

'' |  Select @{N="VM";E={$vm.Name}},

and then remove all the properties that are related to the harddisk


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

View solution in original post

Reply
0 Kudos
9 Replies
LucD
Leadership
Leadership
Jump to solution

With the SearchRoot parameter you can limit the scope from which the Get-View cmdlet returns VMs.

Your function could start something like this

function Get-MyInventory {

  param(

    [String]$Clustername

  )


  $cluster = Get-View -ViewType ClusterComputeResource -Property Name -Filter @{Name="^$ClusterName$"}


  $report = foreach($vm in (Get-View -ViewType VirtualMachine -SearchRoot $cluster.MoRef -Property       Name,runtime.powerState,runtime.consolidationNeeded,Guest.net,Config.Hardware.numCPU,Config.Hardware.MemoryMB,

  Runtime.Host,Guest.GuestFullName, Config.GuestFullName,Parent,ResourcePool,Config.Hardware.Device,Config.version,Config.Tools.ToolsVersion,guest.toolsversionstatus,

  Config.Files.VMPathName,Config.Template -Server $vc )){


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

SkagnolaII
Contributor
Contributor
Jump to solution

Thanks Luc! Very helpful, as usual. Smiley Happy

It creates the expected csv file. Though, which section should I remove if I don't want additional rows for each VM per attached disk? The output has individual rows for each VM, listing the attached disks.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Leave out the ForEach loop over all the disks.

Replace

$vm.Config.Hardware.Device | where {$_.GetType().Name -eq "VirtualDisk"} |

    Select @{N="VM";E={$vm.Name}},

with

'' |  Select @{N="VM";E={$vm.Name}},

and then remove all the properties that are related to the harddisk


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

Reply
0 Kudos
SkagnolaII
Contributor
Contributor
Jump to solution

Thanks, Luc. Works great.

An aside to this, if I wanted to use the same function, but instead of passing a cluster name pass a VM name wildcard to pull info, what changes would I need to make to the script?

i.e. Get-MyInventory  'vmprefix-*' or Get-MyInventory 'redhat7*'

Would it be something like:

function Get-MyInventory {
  param(

    [String]$VMName

  )


  $vm= Get-View -ViewType ClusterComputeResource -Property Name -Filter @{Name="^$VMName$"}


  $report = foreach($vm in (Get-View -ViewType VirtualMachine -Property Name,runtime.powerState,runtime.consolidationNeeded,Guest.net,Config.Hardware.numCPU,Config.Hardware.MemoryMB,

  Runtime.Host,Guest.GuestFullName, Config.GuestFullName,Parent,ResourcePool,Config.Hardware.Device,Config.version,Config.Tools.ToolsVersion,guest.toolsversionstatus,

To clarify - I would like to keep all the info being pulled from the VMs when querying against the cluster - cluster name, guest OS, Tools Status, etc. but make adjustments to the query when trying to use VM name wildcards for some that may be spread across disparate clusters but have similar VM names.

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

The ViewType would need to be VirtualMachine

$vm= Get-View -ViewType VirtualMachine -Property Name -Filter @{Name="^$VMName$"}


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

Reply
0 Kudos
SkagnolaII
Contributor
Contributor
Jump to solution

I have below for the VM query. When run against a name wildcard it will sit for a while. There should only be 22 returned items.

If I try a single VM, it will create an outfile, but it is empty.

function Get-MyInventoryVM {
  param(

    [String]$VMName

  )


  $vm = Get-View -ViewType VirtualMachine -Property Name -Filter @{Name="^$VMName$"}


  $report = foreach($vm in (Get-View -ViewType VirtualMachine -SearchRoot $vm.MoRef -Property Name,runtime.powerState,runtime.consolidationNeeded,Guest.net,Config.Hardware.numCPU,Config.Hardware.MemoryMB,

Runtime.Host,Guest.GuestFullName,Config.GuestFullName,Parent,ResourcePool,Config.Hardware.Device,Config.version,Config.Tools.ToolsVersion,guest.toolsversionstatus,

  Config.Files.VMPathName,Config.Template -Server $vc )){
  if($vm.Config.Template){

            $t = Get-View -Id (Get-View $vm.Runtime.Host).Parent

        }

        else{

            $t = Get-View $vm.ResourcePool -Property Name,Parent -Server $vc

            while($t.getType().Name -eq "ResourcePool"){

              $t = Get-View $t.Parent -Property Name,Parent -Server $vc

            }

        }

        if($t.GetType().Name -eq "ClusterComputeResource"){

            $cluster = $t.Name

        }

        else{

            $cluster = "Stand Alone Host"

        }

        while($t.getType().Name -ne "Datacenter"){

            $t = Get-View $t.Parent -Property Name,Parent -Server $vc

        }

        $datacenter = $t.Name

        '' |  Select @{N="VM";E={$vm.Name}},
        @{N='powerState';E={$vm.runtime.powerState}},

        @{N='IP';E={[string]::Join(',',($vm.Guest.Net | %{$_.IpAddress | where{$_.Split('.').Count -eq 4} | %{$_}}))}},

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

        @{N='Memory GB';E={$vm.Config.Hardware.MemoryMB| %{[math]::Round($_/1kb,2)}}},

        @{N='vCenter';E={$vc.Name}},

        @{N='VMHost';E={$script:esx = Get-View -Id $vm.Runtime.Host -Server $vc ; $script:esx.name}},

        @{N='GuestOS';E={$vm.Guest.GuestFullName}},

        @{N='ConfiguredOS';E={$vm.Config.GuestFullName}},

        #@{N="Folder";E={$path}},

        @{N="Cluster";E={$cluster}},

        @{N="Datacenter";E={$datacenter}},

      @{N='VMConfigFile';E={$VM.config.files.VMpathname}},

      @{N='VMDKPath';E={$_.Backing.FileName}},

      @{N="HW Version";E={$vm.Config.version}},

      @{N="VMware Tools version";E={$vm.Config.Tools.ToolsVersion}}, 

      @{N="Tools Status";E={$vm.guest.toolsversionstatus}},

      @{N="NIC Name";E={($vm.config.hardware.device | where {($_.DeviceInfo.Label -like "Network*")}).DeviceInfo.Label}},

      @{N="Mac"; E={($vm.Config.Hardware.Device | where{$_.DeviceInfo.Label -like "Network*"}).MacAddress}},

      @{N="Portgroup"; E={

        $nic = $vm.Config.Hardware.Device | where{$_.DeviceInfo.Label -like "Network*"}

        [string]::Join(',',(

          $nic | %{

          if($_.DeviceInfo.Summary -notmatch 'DVSwitch'){

            $_.DeviceInfo.Summary

          }

          else{

            Get-View -ViewType DistributedVirtualPortgroup -Property Name -Filter @{'Key'=$_.Backing.Port.PortgroupKey} -Server $vc  |

            Select -ExpandProperty Name

          }}))}}

    }
    $report | Export-Csv c:\reportvm.csv -NoTypeInformation -UseCulture
}

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Remember that the Filter expects a RegEx in the right-hand operator of the comparison.
An '*' will not work.

What are you passing along in VMname?


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

Reply
0 Kudos
SkagnolaII
Contributor
Contributor
Jump to solution

Ah, yep. That's right! Forgot about that.

Also something to note, these VM names include a '-'

I am using the wildcard like this: Get-MyInventoryVM 'aaa-vmname*'.

I wonder if I should do a separate, out flatfile like: Get-VM 'aaa-vmname*' | Select Name | Sort Name | Export-csv c:\out.txt ...

... then source the above outfile in a Import-csv?

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Well that asterisk is a special character in a RegEx.

So that will not work as you intended it.

If you want the VMs that start with 'aaa-vmname', you can use "^aaa-vmname"


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

Reply
0 Kudos