VMware Cloud Community
jaydo123
Contributor
Contributor

Help with script to gather cluster info

Hi

I know that this is something simple am just can't work it out

when I run this script

Connect-VIServer "XXXXXXX"
$ClusterReport = @()
Foreach($cluster in Get-Cluster ){
    $esx = $cluster | Get-VMHost   
    $ds = Get-Datastore -VMHost $esx | where {$_.Type -eq "VMFS" -and (Get-View $_).Summary.MultipleHostAccess}
       
    $row = "" | Select VCname,DCname,Clustername,"Total Physical Memory (GB)",
                "Configured Memory (GB)","Available Memroy (GB)",
                "Total CPU (Mhz)","Configured CPU (Mhz)",
                "Available CPU (Mhz)","Total Disk Space (GB)",
                "Configured Disk Space (GB)","Available Disk Space (GB)",
                "Nr of hosts","Nr of VMs"
    $row.VCname = $cluster.Uid.Split(':@')[1]
    $row.DCname = (Get-Datacenter -Cluster $cluster).Name
    $row.Clustername = $cluster.Name
    $row."Total Physical Memory (GB)" = "{0:f1}" -f (($esx | Measure-Object -Property MemoryTotalMB -Sum).Sum / 1KB)
    $row."Configured Memory (GB)" = "{0:f1}" -f (($esx | Measure-Object -Property MemoryUsageMB -Sum).Sum / 1KB)
    $row."Available Memroy (GB)" = "{0:f1}" -f (($esx | Measure-Object -InputObject {$_.MemoryTotalMB - $_.MemoryUsageMB} -Sum).Sum / 1KB)
    $row."Total CPU (Mhz)" = ($esx | Measure-Object -Property CpuTotalMhz -Sum).Sum
    $row."Configured CPU (Mhz)" = ($esx | Measure-Object -Property CpuUsageMhz -Sum).Sum
    $row."Available CPU (Mhz)" = ($esx | Measure-Object -InputObject {$_.CpuTotalMhz - $_.CpuUsageMhz} -Sum).Sum
    $row."Total Disk Space (GB)" = "{0:f1}" -f (($ds | where {$_.Type -eq "VMFS"} | Measure-Object -Property CapacityMB -Sum).Sum / 1KB)
    $row."Configured Disk Space (GB)" = "{0:f1}" -f (($ds | Measure-Object -InputObject {$_.CapacityMB - $_.FreeSpaceMB} -Sum).Sum / 1KB)
    $row."Available Disk Space (GB)" = "{0:f1}" -f (($ds | Measure-Object -Property FreeSpaceMB -Sum).Sum / 1KB)
    $row."Nr of hosts" = @($esx).Count
    $row."Nr of VMs" = ($esx | Measure-Object -InputObject {$_.Extensiondata.Vm.Count} -Sum).Sum
    $ClusterReport += $row
}
$HostReport = @()
ForEach ($esx in ($Cluster | Get-VMhost | Sort-Object -Property Name)) {
  $Report = "" | select Hostname, version, Build, manufacture, Model,cpu_model, core_num, totalmemoryMB
  $Report.Hostname = $esx.Name
  $Report.version =$esx.Version
  $Report.Build =$esx.Build
  $Report.manufacture =$esx.ExtensionData.Hardware.SystemInfo.Vendor
  $Report.Model =$esx.Model
  $Report.cpu_model =$esx.ExtensionData.Summary.Hardware.CpuModel
  $Report.core_num =$esx.ExtensionData.Hardware.CpuInfo.NumCpuCores
  $Report.totalmemoryMB =$esx.MemoryTotalMB
  $HostReport += $Report
}
$VmInventory = @()
ForEach ($VM in ($Cluster | Get-VM | Sort-Object -Property Name)){
  ForEach ($HardDisk in ($VM | Get-HardDisk | Sort-Object -Property Name)){
    $VmInventory += "" | Select-Object -Property @{N="VM";E={$VM.Name}},
    @{N="Cluster";E={$Cluster.Name}},
    @{N="Host";E={$vm.Host.Name}},
    @{N="IP";E={[string]::Join(',',$VM.Guest.IPAddress)}},
    @{N="NIC";E={$vm.NetworkAdapters.Count}},
    @{N="Operating System";E={$vm.Guest.OSFullName}},
    @{N="CPU";E={$vm.NumCpu}},
    @{N="Memory(GB)";E={($VM | select -ExpandProperty MemoryMB)/1KB}},
    @{N="Hard Disk";E={$HardDisk.Name}},
    @{N="VMConfigFile";E={$VM.ExtensionData.Config.Files.VmPathName}},
    @{N="VMDKpath";E={$HardDisk.FileName}},
    @{N="VMDK Size";E={($vm.extensiondata.layoutex.file|?{$_.name -contains $harddisk.filename.replace(".","-flat.")}).size/1GB}}
  }
}
$ClusterReport | Export-Csv -NoTypeInformation -UseCulture -Path "ClustersReport.csv"
$HostReport | Export-Csv –NoTypeInformation -useCulture -Path "HostsReport.csv"
$VmInventory | Export-Csv -NoTypeInformation -UseCulture -Path "VmsInventory.csv"

I keep getting this error

Get-Datastore : Cannot validate argument on parameter 'RelatedObject'. The argument is null or empty. Supply an argument that is not nul

l or empty and then try the command again.

At C:\Users\jsmith484\AppData\Local\Temp\5e5cf258-a98e-4aee-9579-b839dd190f25.ps1:9 char:32

+     $ds = Get-Datastore -VMHost <<<<  $esx | where {$_.Type -eq "VMFS" -and (Get-View $_).Summary.MultipleHostAccess}

    + CategoryInfo          : InvalidData: (:) [Get-Datastore], ParameterBindingValidationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetDatastore

I think it's something to do with the way that getting the cluster info

if I change  it to gather the info pre clustername like so it works fine

Connect-VIServer hpvvcs001

$clusterName = Read-host "enter Cluster name"

$ClusterReport = @()

Foreach($cluster in Get-Cluster -Name $clusterName){

    $esx = $cluster | Get-VMHost   

    $ds = Get-Datastore -VMHost $esx | where {$_.Type -eq "VMFS" -and (Get-View $_).Summary.MultipleHostAccess}

Reply
0 Kudos
1 Reply
mattboren
Expert
Expert

Hello, jaydo123-

By the error, it seems that there might be a cluster that has no hosts in it.  Do you know of such a cluster in your environment?  I tested in an environment with an empty cluster, and with the original code, received the same error that you reported.

You could quickly check for clusters and their number of hosts with:

Get-Cluster | Select-Object Name,@{n="NumHosts"; e={($_.ExtensionData.Host | Measure-Object).Count}}

If it is the case that a host-less cluster is causing issue here (and, to make the script a bit more flexible), you could change that first portion of the first Foreach loop to something like:

Foreach ($cluster in Get-Cluster) {
   
$esx = $cluster | Get-VMHost
   
## only get datastores if Get-VMHost returned any hosts
    $ds = if ($esx) {Get-Datastore -VMHost $esx | where {$_.Type -eq "VMFS" -and (Get-View $_).Summary.MultipleHostAccess}} else {$null}
    ...

That way, it will only call Get-Datastore each time through if there were VMHosts in the cluster for which the script is currently gathering data.

What kind of a difference does that make for you?

Reply
0 Kudos