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
Leave out the ForEach loop over all the disks.
Replace
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
With the SearchRoot parameter you can limit the scope from which the Get-View cmdlet returns VMs.
Your function could start something like this
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
Thanks Luc! Very helpful, as usual.
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.
Leave out the ForEach loop over all the disks.
Replace
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
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.
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
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
}
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
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?
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