Everyone,
I wrote this script to gather some datastore information and I am looking to see if there is anyway to improve on it. It is working currently but just wondering if some of you powershell guru's wouldnt mind looking it over once for me. Right now I am gathering VMFS friendly name, UUID, VMHBA, BlockSize, Capacity and FreeSpace. Thanks for any input.
*
Connect-VIServer localhost
*
$report = @()
$alldstores = Get-Datastore
foreach ($ds in $alldstores){
$dsfree = ($ds | Get-View).info
$dsinfo = ($ds | Get-View).info.vmfs
$row = "" | Select Name, Diskname, UUID, Capacity, BlockSizeMB, Freespace
$row.name = $dsinfo.Name
$hbas = ""
foreach ($extent in $dsinfo.Extent) {
if ($hbas.Length > 0) { $hbas += " " }
$hbas += $extent.DiskName
}
$row.diskname = $hbas
$row.uuid = $dsinfo.Uuid
$row.capacity = $dsinfo.Capacity /1024MB
$row.FreeSpace = $dsfree.freespace /1024MB
$row.blocksizemb = $dsinfo.BlockSizeMb
$report += $row}
$report | Export-Csv .\dsinfo.csv -NoTypeInformation
*
Disconnect-VIServer -Confirm:$false
*
Looks quit good. Well done.
A few minor suggestions:
*) you can avoid the use of 1 Get-View by using a temporary variable to store the result
*) 1024MB is the same as 1GB
*) format the numbers to only have 2 decimals. Makes the reading easier
$report = @() $alldstores = Get-Datastore foreach ($dsImpl in $alldstores){ $ds = $dsImpl | Get-View $dsfree = $ds.info $dsinfo = $ds.info.vmfs $row = "" | Select Name, Diskname, UUID, Capacity, BlockSizeMB, Freespace $row.name = $dsinfo.Name $hbas = "" foreach ($extent in $dsinfo.Extent) { if ($hbas.Length > 0) { $hbas += " " } $hbas += $extent.DiskName } $row.diskname = $hbas $row.uuid = $dsinfo.Uuid $row.capacity = "{0:N2}" -f ($dsinfo.Capacity /1GB) $row.FreeSpace = "{0:N2}" -f ($dsfree.freespace /1GB) $row.blocksizemb = $dsinfo.BlockSizeMb $report += $row } $report | Export-Csv .\dsinfo.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Looks quit good. Well done.
A few minor suggestions:
*) you can avoid the use of 1 Get-View by using a temporary variable to store the result
*) 1024MB is the same as 1GB
*) format the numbers to only have 2 decimals. Makes the reading easier
$report = @() $alldstores = Get-Datastore foreach ($dsImpl in $alldstores){ $ds = $dsImpl | Get-View $dsfree = $ds.info $dsinfo = $ds.info.vmfs $row = "" | Select Name, Diskname, UUID, Capacity, BlockSizeMB, Freespace $row.name = $dsinfo.Name $hbas = "" foreach ($extent in $dsinfo.Extent) { if ($hbas.Length > 0) { $hbas += " " } $hbas += $extent.DiskName } $row.diskname = $hbas $row.uuid = $dsinfo.Uuid $row.capacity = "{0:N2}" -f ($dsinfo.Capacity /1GB) $row.FreeSpace = "{0:N2}" -f ($dsfree.freespace /1GB) $row.blocksizemb = $dsinfo.BlockSizeMb $report += $row } $report | Export-Csv .\dsinfo.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks so much for the suggestions!
LucD,
I am trying to add the corresponding Cluster and/or hosts to this script so that in the output we wil be able to know which datastore go where. I am running into some problems getting that to work. Any chance you can assist me? Thanks
Jason
With the following adaptation of the script you can add the ESX hostname to each row.
The link to the cluster requires a bit more coding since there is no direct link from the datastore object to the cluster.
$report = @() $alldstores = Get-Datastore foreach ($dsImpl in $alldstores){ $ds = $dsImpl | Get-View $dsfree = $ds.info $dsinfo = $ds.info.vmfs foreach ($extent in $dsinfo.Extent) { if ($hbas.Length > 0) { $hbas += " " } $hbas += $extent.DiskName } foreach($esx in $ds.Host){ $row = "" | Select Name, Diskname, UUID, Capacity, BlockSizeMB, Freespace, ESXname $row.name = $dsinfo.Name $hbas = "" $row.diskname = $hbas $row.uuid = $dsinfo.Uuid $row.capacity = "{0:N2}" -f ($dsinfo.Capacity /1GB) $row.FreeSpace = "{0:N2}" -f ($dsfree.freespace /1GB) $row.blocksizemb = $dsinfo.BlockSizeMb $row.ESXname = (Get-View $esx.Key).Name $report += $row } } $report | Export-Csv .\dsinfo.csv -NoTypeInformation
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Thanks LucD,
That worked great, last question if I wanted to import a csv with just a few hosts on it and find all the same info how could I do that? I tried adding the following
$report = @()
$vmhosts = Import-Csv "d:\scripts\hostinfo.csv"
foreach ($vmhost in $vmhosts){
$alldstores = Get-VMhost $VMHost | Get-Datastore
But it keeps erroring out, saying that the hosts are not found. Can you assist one more time please? Thanks.
I suspect you have a CSV file with this layout
HostName host1.domain1 host2.domain2
If you read this with the Import-Csv cmdlet you will get an array of PsCustomObjects.
To get at the name of the host (a string) you have to address the HostName property (based on the above CSV example)
Something like this:
$report = @() $vmhosts = Import-Csv "d:\scripts\hostinfo.csv" foreach ($vmhost in $vmhosts){ $alldstores = Get-VMhost $VMHost.HostName | Get-Datastore ...
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference