VMware Cloud Community
Shoganator
Enthusiast
Enthusiast

[Script] Get stats on all Datastores as well as which VMs are running on each

Hi guys,

Just thought I would post this up here - it is a "Datastore Reporting" PowerCLI script that I have been working on in my spare time that lists all the Datastores in your vSphere environment, and gives you statistics on them - Free Space, Capacity, and an Extra that I did a VIProperty Module for - PercentFree. (You'll need LucD's awesome VIProperty module for this to run properly! - Make sure you get the latest version to get the small VIProperty I did for PercentFree too).

In addition to all the datastores in your environment, the script will also collect the names of VMs running on these datastores, and list them below each datastore's stats. (Templates are not supported). You will also get a column to indicate whether or not the VM is powered on. Note that this of course lists the VM name for that datastore if the VM has at least one VMDK on the datastore - so if a VM has multiple disks on various datastores, it may appear on more than one datastore Smiley Wink

I got a bit of help to figure out the VM names part of this script (fetched via ExtensionData) over here from @mattboren and @LucD http://communities.vmware.com/thread/336078 - thanks for that guys Smiley Happy

Here is a screenshot of the email report you'll receive:

http://dl.dropbox.com/u/450727/scripts/Datastore-Report/ds-report.jpg

And here is a link to download the all important script Smiley Happy

http://dl.dropbox.com/u/450727/scripts/Datastore-Report/datastore-report.ps1

Script for those who have dropbox blocked on their firewalls etc:

# Datastore & VM Report
# By Sean Duffy (aka Shoganator on VMware Communities)
# 13/11/2011
# Uses - PowerCLI, VIProperties Module (get VIProperties from: http://www.lucd.info/viproperties/)
Import-Module VIProperty
$users = "yourmail@yourdomain.com" # List of users to email your report to (separate by comma)
$server = "yourmailserver.com" #enter your own SMTP server DNS name / IP address here
$datastore = $null
$Report = @()
$AllDatastores = Get-Datastore | Where {$_.Name -notlike "datastore*"} | Sort Name
foreach ($datastore in $AllDatastores) {
$Report += "<TD>"
$row = "" | Select Name, FreeGB, CapacityGB, PercentFree
$row.Name = $datastore.Name
$row.FreeGB = $datastore.FreeGB
$row.CapacityGB = $datastore.CapacityGB
$row.PercentFree = $datastore.PercentFree
$Report += $row | ConvertTo-Html
#List VMs on the datastore if applicable
If ($datastore.ExtensionData.Vm.Count -gt 0){
$VMList = Get-View -Id $datastore.ExtensionData.Vm -Property Name | Select Name
$Report += "<BR></BR>"
$Report += "<B><U>VMs on this Datastore:</U></B>"
$VMTable = @()
foreach ($vm in $VMList) {
$VMContentRow = "" | Select Name, PowerState
$tmp = Get-VM $vm.Name
$VMContentRow.Name = $tmp.Name
Write-Host $tmp.Name
if ($tmp.PowerState -eq "PoweredOn") {
$VMContentRow.PowerState = $tmp.PowerState
}
else {
$VMContentRow.PowerState = $tmp.PowerState
}
$VMTable += $VMContentRow
}
$Report += $VMTable | ConvertTo-Html -Fragment
}
else {
$Report += "<BR></BR>"
$Report += "<B><U>VMs on this Datastore:</U></B>"
$Report += "<table style=""background-color: #FFCC99""><tr align=""center""><th>Name</th></tr>"
$Report += "<td align=""center"">No VMs on this Datastore</td></table>"
}
$Report += "<BR></BR>" #Line break for clarity
$Report += "</TD>"
}
$Report | Set-Content C:\DSReport.html #Also write to an HTML report on disk - with basic formatting, in addition to the email report you are sent.
# HTML formatting for email
$HTMLmessage = @"
<font color=""black"" face=""Arial, Verdana"" size=""3"">
<u><b>Datastore Report</b></u>
<br></br>
<br></br>
<style type=""text/css"">body{font: .8em ""Lucida Grande"", Tahoma, Arial, Helvetica, sans-serif;}
ol{margin:0;padding: 0 1.5em;}
TABLE{border-width: 1px;border-style: solid;border-color: black;}
TH{border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
TD{text-align:center;border-width: 1px;padding: 5px;border-style: solid;border-color: black;}
table{color:#000;background:#99CCFF;border-collapse:collapse;width:647px;border:3px solid #900;}
thead{}
thead th{padding:1em 1em .5em;border-bottom:1px dotted #FFF;font-size:120%;text-align:left;}
thead tr{}
td{padding:.5em 1em;}
tfoot{}
tfoot td{padding-bottom:1.5em;}
tfoot tr{}
#middle{background-color:#900;}
</style>
<body BGCOLOR=""white"">
$Report
</body>
"@
#Send the final report!
send-mailmessage -from $fromemail -to $users -subject "Datastore Report" -BodyAsHTML -body $HTMLmessage -smtpServer $server

I'm sure there are areas that could be improved, so please feel free to change if you like - just be sure to post back your addition's / extra functionality you have added here! Hope this helps any one looking for this kind of info in a nicely formatted E-mail report Smiley Happy

Cheers,

Sean

Message was edited by: Shoganator - trying out better syntax highlighting.

My personal blog: http://www.shogan.co.uk .::. Twitter: shogan85 .::. if an answer has helped or solved your question, please don't forget to mark as "Answered" or "Helpful"!
0 Kudos
12 Replies
LucD
Leadership
Leadership

Great script, attractive and pleasing output.

Thanks for mentioning the VIProperty module :smileyblush:


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

0 Kudos
nielse
Expert
Expert

Nice script! I only get some errors on templates on datastores "VM with name '....' was not found using the specified filter(s)".

@nielsengelen - http://foonet.be - VCP4/5
0 Kudos
Shoganator
Enthusiast
Enthusiast

Thanks Nielse!

Yes, templates not supported at the moment - you'll get a blank row for all the places where Templates are found in the final report. (As well as seeing a bit of red error in the shell). I'm sure there would be an easy fix for that - just work out whether object is template, if so, skip the data gathering part of the loop for that object, until the next object on the next loop iteration. Check if template or not, continue, etc... Smiley Happy

My personal blog: http://www.shogan.co.uk .::. Twitter: shogan85 .::. if an answer has helped or solved your question, please don't forget to mark as "Answered" or "Helpful"!
0 Kudos
mattboren
Expert
Expert

Hello, Shoganator-

Decent script, thanks for sharing.  Glad to have helped a little.

And, as for the "handling templates" part, I updated the main portion of the code such that it does account for templates, now.  So, the top half of the code (down to where it does the Set-Content C:\DSReport.html), is updated as such:

Import-Module VIProperty

$users = "yourmail@yourdomain.com" # List of users to email your report to (separate by comma)
$fromemail = "yourmail@yourdomain.com"
$server = "yourmailserver.com" #enter your own SMTP server DNS name / IP address here

$Report = @()
## done to exclude local datastores?
$AllDatastores = Get-Datastore | Where {$_.Name -notlike "datastore*"} | Sort Name
foreach ($datastore in $AllDatastores) {
   
$Report += "<TD>"
   
$row = New-Object -Type PSObject -Property @{
        Name
= $datastore.Name
        FreeGB
= $datastore.FreeGB
        CapacityGB
= $datastore.CapacityGB
        PercentFree
= $datastore.PercentFree
    }
## end new-object
    $Report += $row | ConvertTo-Html

   
#List VMs on the datastore if applicable
    $Report += "<BR></BR>"
   
$Report += "<B><U>VMs/Templates on this Datastore:</U></B>"
   
if ($datastore.ExtensionData.Vm.Count -gt 0){
       
$VMViewList = Get-View -Id $datastore.ExtensionData.Vm -Property Name,Runtime.PowerState,Config.Template
       
$VMTable = @()
       
foreach ($viewVM in $VMViewList) {
           
Write-Host $viewVM.Name
           
$VMContentRow = New-Object -Type PSObject -Property @{
                Name
= $viewVM.Name
                PowerState
= $viewVM.Runtime.PowerState
                Other
= if ($viewVM.Config.Template) {"Template"} else {"VM"}
            }
## end new-object
            $VMTable += $VMContentRow
        }
       
$Report += $VMTable | ConvertTo-Html -Fragment
    }
## end if
    else {
       
$Report += '<table style="background-color: #FFCC99"><td align="center">None on this Datastore</td></table>'
    }
## end else

   
$Report += "<BR></BR>" #Line break for clarity
    $Report += "</TD>"
}
## end foreach

$Report | Set-Content C:\DSReport.html #Also write to an HTML report on disk - with basic formatting, in addition to the email report you are sent.
...

The changes that I made:

  • removed "$datastore = $null" line (not necessary)
  • cleaned up code (some redundant items, or needless (like the if statement for setting "$VMContentRow.PowerState = $tmp.PowerState" -- is was doing the same thing for "if" and for "else" conditions)
  • changed to use New-Object instead of <"" | Select ...> construct (two places)
  • changed from using Get-VM to leveraging the existing Get-View, and getting powerstate from that (can tell if item is a template, too)
    • this removes the extra Get-VM call (one per every VM) -- speed boost
    • this handles templates now, too
  • added field that shows whether item is VM or template

Again, thanks to using the VM data from the existing Get-View call (just added a couple of properties to the call), this no longer uses the Get-VM call, which speeds up the script by about 30% in my testing.  Another way to speed it up would be to use Get-View for getting the datastores, but then that would kind of defeat the whole strategy of using the VIProperty module.

I did not change the other (bottom) portion of the script.  Thanks again for sharing.  Let me know how these updates do for you.

Message was edited by mattboren:  BTW, you can disregard the hyperlinks on the email addresses at the top -- the Communities forum software inserts those; it does not affect the code upon a copy/paste, it seems

0 Kudos
Shoganator
Enthusiast
Enthusiast

Hi mattboren

Thanks very much for checking it out and making some improvements. I was wondering about Get-View. I haven't used it much before, so will try get the hang of it as I go on. I ran this on an environment of around 300 VMs and realised that some extra speed was needed when fetching the VMs, so this should work out nicely now Smiley Happy

I'll have a try with your revised script tomorrow and will update the link to get the script. (Or should I rather add it as a VMware Community document and attach to a post?).

Sean

My personal blog: http://www.shogan.co.uk .::. Twitter: shogan85 .::. if an answer has helped or solved your question, please don't forget to mark as "Answered" or "Helpful"!
0 Kudos
srfhrd
Contributor
Contributor

Mattboren/Shoganator,

First of all, thank you very much for the script it's amazing, I was wondering if is possible to add a few fields to the script, I am dealing with storage over allocation problem, so the script works fine, but I need the following to be added and maybe learn how to do it:

ProvisionedSpaceinGB

FreeSpaceinGB

AllocationPercent

And finally, how may I add the following values to the List of VM's in the datastore:

get-vm | sort | % {$_.name; ($_|get-harddisk | % {$_.filename;$_.capacitykb})}

This will list the VM name the datastore and the location of the VMDK example:

VM name

[DATASTORE_NAME_LUN_01] VM_NAME/VM_NAME.vmdk

100240

[DATASTORE_NAME_LUN_01] VM_NAME/VM_NAME.vmdk

200480

By the way the Percent Free Space came up empty, any thoughs?  I'll forward to hear from you.

Thanks,

0 Kudos
Shoganator
Enthusiast
Enthusiast

Hi,

For the missing percent - did you install LucD's VIProperties? Grab them here and follow instructions to install them where you are running the script - http://www.lucd.info/viproperties/ that should sort out the missing percent issue for you Smiley Happy Make sure the VIProperties are loaded in your PowerCLI environment where you run the script!

I'll take a look at adding your requirements to the script I originally did over the weekend when I get a chance (hopefully I can!) Smiley Happy

My personal blog: http://www.shogan.co.uk .::. Twitter: shogan85 .::. if an answer has helped or solved your question, please don't forget to mark as "Answered" or "Helpful"!
0 Kudos
srfhrd
Contributor
Contributor

Shoganator,

Thank you for getting back to me, I'll be standing by awaiting for your response.

0 Kudos
Shoganator
Enthusiast
Enthusiast

Ok, spent quite a bit of time trying to get this working but I wasn't having much luck. I need to be in a clear frame of mind to get this working nicely. Unfortunately I am bogged down with work at the moment and have little time outside of work to do this either, so the best I can do for you now is adding the ProvisionedGB figure you wanted:

http://dl.dropbox.com/u/450727/scripts/Datastore-Report/datastore-report_01.ps1

That will give you that bit. As for:

FreeSpaceinGB

AllocationPercent

Those are already included in the original script! As I mentioned, you need to install VIProperties - go to the post I linked you to, follow the install instructions, and make sure that the VIProperties module is loaded when the script calls "Import VIProperties" at the start. That will give you the free space percent. If you want to work out the used/allocated Percent, just simply minus the Free percent from 100% and add that into another column in the table.

If I had more time I would happily work on this, but right now life is a bit hectic for me Smiley Happy

My personal blog: http://www.shogan.co.uk .::. Twitter: shogan85 .::. if an answer has helped or solved your question, please don't forget to mark as "Answered" or "Helpful"!
0 Kudos
afhamsani
Enthusiast
Enthusiast

i try to understand few lines as such as this, what does it means by +=

$Report += "<TD>"

0 Kudos
LucD
Leadership
Leadership

It's short for

$Report = $Report + "<TD>"


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

0 Kudos
afhamsani
Enthusiast
Enthusiast

Thanks mate, got it

0 Kudos