Quicky#1 Get csv report on virtual machine partitions in cluster/multiple clusters

I was asked today how to do that kind of report. It’s really handy to have one of those, and i was surprised that i haven’t wrote about that so far on my blog. So here it is 😉

$(foreach ( $cluster in 'xyz1','yxx2' ) { get-view -SearchRoot (get-cluster $cluster).id -viewtype VirtualMachine -Filter @{"Summary.Runtime.PowerState"="poweredOn";"Config.Template"="False"}  | % {$esxhost=(get-view ($_.Summary.Runtime.Host)).name;$vmname=$_.Name;$_.Guest.Disk | select @{N="VMName";E={$vmname}},DiskPath,@{N="CapacityGB"; E={[Math]::Round($_.Capacity/1GB,2)} },@{N="FeeSpaceGB";E={[Math]::Round($_.FreeSpace/1GB,2)}},@{N="Cluster";E={$cluster} },@{N="Host";E={$esxhost} } }  })  | Export-Csv "c:\ReportVMsDiskUsage.csv" -NoTypeInformation

Yes, i know 😉
IT IS SO LOOOOOOONG 🙂
So what it does. It will output a csv file in my example to c:\ReportVMsDiskUsage.csv”. Contents are : Name of VM, disk letter/path, Capacity in Gb, FreeSpace in GB, Cluster name on which vm resides, Host name on which vm resides.
This one liner looks bit complicated but once disassembled it’s very easy to understand what i am doing.
I am using the sub-expression $ ( ) | Export-csv … . I did that because i want the whole output in my csv file. Without first getting the whole output it’s very hard i suppose to use the export-csv to put it to 1 file. If you want this to run against 1 cluster or more clusters, just adjust the strings in the foreach($cluster in ….) .
It can be very easy to adjust this one liner to ignore cluster, do the report on the highest level. I am using switch -SearchRoot from get-view and giving him the location of get-cluster X. If you do not want to narrow down the results, just don’t use the -SearchRoot, and it will give you output for all vms that are:
-Filter @{“Summary.Runtime.PowerState”=”poweredOn”;”Config.Template”=”False”}
Powered On, and are not tempaltes.
Before sending the output ” $_.Guest.Disk | ….” further , i also grab all other needed properites, like vmname,esxhost.
It also useful to check the output first before sending it to export-csv. So let’s take a look by running :

foreach ( $cluster in 'xyz1','yxx2' ) { get-view -SearchRoot (get-cluster $cluster).id -viewtype VirtualMachine -Filter @{"Summary.Runtime.PowerState"="poweredOn";"Config.Template"="False"}  | % {$esxhost=(get-view ($_.Summary.Runtime.Host)).name;$vmname=$_.Name;$_.Guest.Disk | select @{N="VMName";E={$vmname}},DiskPath,@{N="CapacityGB"; E={[Math]::Round($_.Capacity/1GB,2)} },@{N="FeeSpaceGB";E={[Math]::Round($_.FreeSpace/1GB,2)}},@{N="Cluster";E={$cluster} },@{N="Host";E={$esxhost} } }  }

You will see report on each vm . from each cluster. Then we need to get the WHOLE output as one and send it to export-csv, and this is why i used
sub-expression $() | export-csv… to grab first the whole output. I got loops for each cluster so , i cant export the loop to export-csv, as the file will be overwritten as the end by the last loop output. You could ommit the export-csv and the sub-expression here by sending the output straight to file using ” >> file.csv ” , but in this case you would have to prepare some [string]$line, which will have commas in it so it would look like a csv file.
If you find any bug in my scripts or you know more efficient way to do things describes in my posts, please do comment and share your experience.

Advertisements