PowerCLI: Daily Report

This script will save you time and resources.

I have been using this script for the past month and it has highlighted a number of issues which would have been harder to find without it.

Daily Report does what it says on the tin, it runs as a scheduled task before you get into the office to present you with key information about your infrastructure in a nice easily readable format.

This script picks on the key areas of the virtual infrastructure and reports it all in one place so all you do in the morning is check your email.

One of they key things about this report is if there is no issue in a particular place you will not receive that section in the email, for example if there are no datastores with less than 5% free space (configurable) then the disk space section will not show in the email, this ensures that you have only the information you need in front of you when you get into the office.

So what areas does this script report on ?

Firstly it will give you a very brief summary detailing some of the critical information, it does not list every name and how many cpu’s or how much memory your vms and hosts have as that would be a audit report not a daily report.

image

There is a configurable section at the start of the script where you can set how many days old you would like your snapshots to be allowed in your infrastructure, anything over this will show in the report, it will even resolve the name ( the machine running the script must be part of an Active Directory Domain) so that you can forward this email on to them and ask them if they still need the snapshot.

image

There is a section which lists all datastores that have less than x% free space.

image

The below section notes any virtual machines which have been created in the last x days and who created these.

image

Similarly any VMs which have been deleted.

image

Any Virtual Center Events which have been logged during the given timeframe.

image

Any VM’s which have no VMtools installed.

image

The script will also hook into your virtual center server and tell you what the state of all VMware services are, if you use a different account to access you virtual center than the one which is running the script then you can set this at the start and the first time the script runs after this it will ask you for the credentials of the account and store these in an encrypted file for future use.

image

Also in the report but not screen captured is:

  • Any Windows events from the Virtual center server which are related to VMware
  • Any VMs which have CD-Rom or Floppy Drive’s connected
  • Any hosts in Maintenance Mode
  • Any Hosts ina disconnected state

At the bottom of he script is also an area which you can uncomment to save a the daily report as a htm file in a specific folder.

I think that’s it !

If there is anything missing please let me know and I will add it to future versions.

To run this script simple setup a scheduled task as per my previous post running the script and passing it your VI server as a parameter as below:

C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\vim.psc1″ ” &  “C:\Scripts\DailyReport.ps1 TESTVC01”

Check out the latest version here

162 thoughts on “PowerCLI: Daily Report”

  1. Hello,

    Can you pls share the v1 v2 v3 ie all of the version of this scripts pls ?

    Only latest is vailbale to download, that is fair but that is really too big & i am looking for only small bits of the big one & these older ones looks like what can help me

    Pls give links to download them

    Thanks

  2. @Fred
    Yes it works on ESX 3.5, we have been using it for about 9 months now without any problem.

    Mark

  3. Just curious – will this work on just ESX 3.5 and ESX 3i servers? We are currently not running sphere. It be great to get this for my small environment with 7 production VMs.

    Best Regards,
    Fred Jumayao

  4. Thanks for the comments !

    That definitely sounds like an issue with the smtp settings, are you sure you have them correct, does your smtp server require authentication, can you telnet to the box on port 25 from the machine running the script ?

  5. hey al, all your scripts are awesome, lol i check every week your page to see whats going on !, i was giving a try this Daily report, but i have an error, when it finishes and tryes to send the email with the report

    Exception calling “Send” with “1” argument(s): “Failure sending mail.”

    i’ve already edited the script with the correct mail, and smtp server parameters.

    can you give me a hand here?

  6. On s server 2008 R2 64 bit machine running the latest vcenter I issue the following command at the command line.

    C:\Users\stn1vmadmin>C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1 ” & “c:\scripts\DailyReport.psc1 stnsvpvcenter”

    and I get this error …

    Windows PowerShell console file “”C:\Program” extension is not psc1. Windows PowerShell console file extension must be psc1.

    1. Ok, Try this: C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1″ ” & “c:\scripts\DailyReport.psc1 stnsvpvcenter”

      Note the extra quote. I normally run it from a DOS prompt first to make sure it works.

  7. Hi

    Looks like a great script.
    I would like to know if this script can be used for ESX 3i based environment ?
    I have 2 ESX 3i based environment and of which one is managed by VC and 2nd one without VC.

    Please suggest

    1. Thanks for the comment, to be honest I have not tried it in an unmanaged 3.5 environment, you will probably get a bunch of errors but you should get some info back at least, the script only reads information, there is no writes at all so give it a go, the worst that can happen is it will fail !

      I would be interested in your results !

  8. thanks for the script, how do we point this script to talk to only one datacenter…

    we have multiple datacenters listed in our environment and it will be good if this can point to only one datacenter..

  9. @Amit

    You shouldnt need to ammend the code, just add the name of your vCenter server after the name of the script, it will then use this as a parameter, ie:

    C:\Scripts\DailyReport.ps1 TESTVC01

  10. I cannot get the script to run and connect to my vCenter Server. Keeps saying specify a VI server name. I have tried to do this and also edit the script to include this but still not running…can anyone help ?

  11. @Marc
    I have never seen that before, it sounds like you are making two connections, im not even sure that can be done !

    Have you modified any part of my script at all ?

    What happens if you connect to your host manually through PowerCLI and do a get-vmhost, do you get duplicate Hosts then ?

  12. Hi I must thank you for the excellent script you make.
    I have only have one problem.
    I don’t know what happens but every time I run this script I get the information twice in my report.
    for example I have 7 hosts and my report gives 14 etc.
    Can you maby explain what is going wrong.
    regards,

    Marc

  13. Thanks. I need that part of script and i’ve introduced a small trap to continue on errors.

    – One more Query regarding the number of slots in the clusters. In my environment there are 4 clusters with differnet number of slots.

    – What value should i put for $numslots.

    Appreciate your help.

  14. @Rajeev

    You can turn that part of the script off if you dont need it, check near the top, it will probably speed it up for you too.

  15. Hi,

    Great script and is very useful. Couple of my ESX servers doesnt have LUN’s presented, has only local HD. So the script fails at get-scsilun cmdlet. Is there some kind of error handling we could introduce?

    Please help

  16. The Script runs well, except at some points at the following exception.

    15:38 ..Checking Snapshots
    Exception calling “ReadNextTasks” with “1” argument(s): “A general system error
    occurred: Object not found”
    At C:\tools\VMware_Daily_Report3.ps1:420 char:45
    + $collection = $collectionImpl.ReadNextTasks( <<<< $tasknumber)
    Exception calling "ReadNextTasks" with "1" argument(s): "A general system error
    occurred: Object not found"

  17. Thank you, it worked for both v2 and v3. The information reported is very helpful. I used it today and taking some actions on what was reported already i.e. snapshots, vmotion violations.

    Excellent!
    -N

  18. @nsocrates
    This part is used to communicate to your vCenter server over WMI, if your current account has access to that servers then you will be fine and do not have to set this, if not then this file is auto-created by the script, all you need to do is put a username in the $SetUsername = “” bit, so if I set it to $SetUsername = “mydomain\me” then next time you run the script it will ask you for a username and password, enter the same username (mydomain\me) and the password.

    The credentils will then be stored in that file encrypted so that every other time you run the script it will have the correct permissions.

    A little complicated I know but it was the easiest way I could find of doing it.

  19. hello, i’m trying to run v2 of the script and there is a part that references “mycred.crd” file. I’ve placed uid/pw but it doesn’t take it. How is this file supposed to be created?

    Thanks,
    -N

  20. @Andrea
    The vCenter bit at the end is the hostname of your virtual center, it passes the information as a parameter to the script, What I normally do is run my cmd from a dos prompt until it works and then copy and paste the line into the run window of the scheduled task.

  21. Hello
    i don’t resolve the Scheduled TASK!!
    Have you got a Guide (or requisites) sto solve this line?

    C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1″ ” & “c:\scripts\ps\VMware_Daily_Report.ps1 vCenter”

    I’ve find error of Set-ExecutionPolicy and i set the line in this mode:

    C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe Set-ExecutionPolicy Unrestricted…
    but don’t work.
    The “VMware_Daily_Report.ps1” is this file PowerCli?
    What’s the word at the and of the line “vCenter” ?
    Why there’s a double > ″ ” in the middle?

  22. @Virtu-Al
    Yes, I have enabled the HTML output which does appear as your sample when viewed in IE. But it doesn’t appear to use the text formatting when we view it as e-mailed in MS Outlook.

  23. @Dan Yates
    Hmmm, havent seen that one before, would you be able to email me a copy of your results please ? My contact information is in the contact me tab at the top of this page.

  24. Alan, really like this script and would like to adopt as part of our internal health checks, however at the end I am getting the table with services and then just after the table it repeats the last two entries again, see below:

    VMware Update Manager ServiceRunningAutoOK VMware VirtualCenter ServerRunningAutoOK
    /html>

    It also ends there without any vmkernel messages section, am I missing something?

    Thanks again,

    Dan

  25. @Graham
    You could try something like this… replace your mail function in the script with:

    function Send-SMTPmail($to, $from, $subject, $smtpserver, $body) {
    $mailer = new-object Net.Mail.SMTPclient($smtpserver)
    $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
    $mailer.Credentials = New-Object System.Net.NetworkCredential(“username”, “passwd”);
    $msg.IsBodyHTML = $true
    $mailer.send($msg)
    }

  26. Alan,

    great script. Unfortunately i need to relay mail through a secure exhange environment and need to authenticate to the server to said mail. Is there an easy way to do this?

  27. I just scheduled the script on a Windows Server 2008 x64 machine and want to share the commando: C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files (x86)\VMware\Infrastructure\vSphere PowerCLI\vim.psc1″ ” & “c:\scripts\ps\VMware_Daily_Report.ps1 vCenter”

  28. @Virtu-Al After some playing I finally got the disk usage for VM’s it works really well. Thanks again for the great script to work from.

  29. @edward
    You will need to configure the account which has permissions for your vc its one of the options near the top of the script. Let me know if you need me to video it as its not as easy as id like.

  30. @Mark
    The output should be defined by your html renderer for your email client, have you tried saving the content as a html file which can be enabled at the bottom of the script or try a different email client.

  31. Cheers Alan, this is a great script. I can leave VC to do it’s own thing now and see what’s going on with this report. What a life saver.

  32. Hi again, i add “@{N=”Host”;E={$_.host.name}}” in VC errors loop to get hostname for any error (if not VC)
    Hope it help for future version 😉

  33. Hi lovely script it works well for me . The only problem is the services section is empty ..Looks like a Aceess denied error

  34. Very nice.
    Not being a windows person and not up to snuff on Powershell, what would you suggest to cleanly update this script to ignore certificate errors when connecting to the virtual center instance? It does connect, but this script will fail if certificates are not set up. Was able to hard code removing lines 396 thru 400 and all went well. Not elegant, but got the job done. Thanks.

  35. Love the script, modified the ‘No Vm Tools’ section as Killsystem posted to include VMs with outdated tools also.

    A question though, my output does not appear as you screenshots above show. Rather than red and blue headers with white lettering, I only get white backgrounds with black letters. Is there a switch to turn on/off the formatting that I have missed?

    Thanks
    Mark

  36. Al, as i get some false values on ToolsVersion, i replace “Where { $_.ToolsVersion -eq 0}” by “Where {$_.guest.toolsstatus -eq “toolsNotInstalled” -or $_.guest.toolsstatus -eq “toolsNotRunning”}”

  37. Ahh nice 🙂 my Testcluster is allready on vSphere fo your information the script works nice with vSphere!

    I will run it than on my vi3 production cluster thanks a lot!

    regards

    Daniel

  38. @Killsystem
    Thanks for the comments, I was thinking of making all sections optional, just change a switch in the config section, vSphere Hardware is a great idea, I will add this when I get a vSphere test Environment running.

  39. @Alex
    There is a couple of ways to do it but all require a third party tool or dll to do this, I will consider putting it in. Thanks for the idea.

  40. @Archie
    Sounds like the account you ran it as does not have permissions on the VC server you were connecting to. Try again with correct permissions, let me know if you need any further help.

  41. @bob
    Do you get no output at all ? Thats very strange. Have you tried running it through powergui just to see if that gives any help ?

  42. Alan,

    Always right on! Well done on this script it is an ideal layout. I have been waiting for a PS script similar to this.

    I have a few add on suggestions for the next version:

    Average Cluster CPU/Memory Utilization
    Average Host CPU/Memory Utilization
    Average VM CPU/Memory Utilization
    High Utilization VMs CPU/Memory
    Low Utilization VMs CPU/Memory – VM Sprawl…
    Cluster info – Failover Capacity, Total Migrations

    Thanks,
    Marc

  43. First of all CHEERS! Great program!

    Now I have one question. One of my VC 2.5 uses a non default port ie myserver:8443 which gives me an error when running the script “A port was expected because of there is a colon (‘;’) present but the port could not be parsed.” What can i do to fix this?

    Connecting to the server using VI client on the custom port works fine.

    Thanks

  44. Hi Alan,

    first of all this script sounds fantastic!

    I´m still using vi3 not vsphere is this script only for vsphere or can i also use it with vi3?

    Thank you in advance & Greetings from Germany

    Daniel

  45. I added Hugo Peeter’s inconsistency script to the script (http://www.peetersonline.nl/index.php/vmware/check-vmware-configuration-with-powershell/) to gain some additional functionality. Seems to work fine and just needs a small amount of tweeking and none of the variables need to be changed.

    Remove everything below the “—- VC Errors —-” section in the existing Daily Report script and add the code below at the bottom instead. I left in all commented out lines for clarity.

    #=====================================================================
    #$outputFile = ‘c:\scripts\compare.html’
    #$VCServer = “”

    Function Create-HTMLTable
    {
    param([array]$Array)
    $arrHTML = $Array | ConvertTo-Html
    $arrHTML[-1] = $arrHTML[-1].ToString().Replace(”,””)
    Return $arrHTML[5..1000]
    }

    $output = @()
    #$output += ”
    $output += ‘table{border-style:solid;border-width:1px;font-size:8pt;background-color:#ccc;width:100%;}th{text-align:left;}td{background-color:#fff;width:20%;border-style:solid;border-width:1px;}body{font-family:verdana;font-size:8pt;}h1{font-size:12pt;}h2{font-size:10pt;}’
    $output += ‘VMWARE CONFIGURATION INCONSISTENCIES’
    $output += ‘The following items are not available to all ESX servers in the cluster:’

    #$VC = Connect-VIServer $VCServer

    ForEach ($Cluster in (Get-Cluster | Sort Name))
    {
    $VMHosts = $Cluster | Get-VMHost | Sort Name
    $VMHostViews = $VMHosts | Get-View | Sort Name

    $myDSCol = @()
    $Datastores = Get-Datastore -VMHost $VMHosts
    $DSdiffs = $VMHosts | ForEach {Compare-Object $Datastores (Get-Datastore -VMHost $_) -SyncWindow 1000} | ForEach {$_.InputObject} | Sort Name | Select Name -Unique
    ForEach ($DSdiff in $DSdiffs)
    {
    If ($DSdiff.Name -ne $null)
    {
    $myDSObj = “” | Select Datastore
    $myDSObj.Datastore = $DSdiff.Name
    ForEach ($VMHost in $VMHosts)
    {
    $myDSObj | Add-Member -MemberType NoteProperty -Name $VMHost.Name -Value (!!(Get-Datastore -Name $myDSObj.Datastore -VMHost $VMHost -ErrorAction SilentlyContinue))
    }
    $myDSCol += $myDSObj
    }
    }

    $myLUNCol = @()
    $LUNs = $VMHostViews | ForEach {$_.Config.StorageDevice.ScsiLun | ForEach {$_.Uuid}} | Select -Unique
    $LUNdiffs = @()
    ForEach ($VMHostView in $VMHostViews)
    {
    $HostLUNs = $VMHostView.Config.StorageDevice.ScsiLun | ForEach {$_.Uuid} | Select -Unique
    $LUNdiffs += Compare-Object $LUNs $HostLUNs -SyncWindow 1000 | ForEach {$_.InputObject}
    Clear-Variable HostLUNs -ErrorAction SilentlyContinue
    }
    ForEach ($LUNdiff in ($LUNdiffs | Select -Unique | Sort))
    {
    If ($LUNdiff -ne $null)
    {
    $myLUNObj = “” | Select LunUuid
    $myLUNObj.LunUuid = $LUNdiff
    ForEach ($VMHostView in $VMHostViews)
    {
    If (($VMHostView.Config.StorageDevice.ScsiLun | Where {$_.Uuid -eq $myLUNObj.LunUuid}) -ne $null)
    {
    $myLUNObj | Add-Member -MemberType NoteProperty -Name $VMHostView.Name -Value (($VMHostView.Config.StorageDevice.ScsiLun | Where {$_.Uuid -eq $myLUNObj.LunUuid}).CanonicalName)
    }
    Else
    {
    $myLUNObj | Add-Member -MemberType NoteProperty -Name $VMHostView.Name -Value $False
    }
    }
    $myLUNCol += $myLUNObj
    }
    }

    $myPGCol = @()
    $PortGroups = Get-VirtualPortGroup -VMHost $VMHosts | ForEach {$_.Name} | Select -Unique
    $PGdiffs = @()
    ForEach ($VMHost in $VMHosts)
    {
    $HostPGs = Get-VirtualPortGroup -VMHost $VMHost | ForEach {$_.Name} | Select -Unique
    $PGdiffs += Compare-Object $PortGroups $HostPGs -SyncWindow 1000 | ForEach {$_.InputObject}
    Clear-Variable HostPGs -ErrorAction SilentlyContinue
    }
    ForEach ($PGdiff in ($PGdiffs | Select -Unique | Sort))
    {
    If ($PGdiff -ne $null)
    {
    $myPGObj = “” | Select PortGroup
    $myPGObj.PortGroup = $PGdiff
    ForEach ($VMHost in $VMHosts)
    {
    $myPGObj | Add-Member -MemberType NoteProperty -Name $VMHost.Name -Value (!!(Get-VirtualPortGroup -Name $myPGObj.PortGroup -VMHost $VMHost -ErrorAction SilentlyContinue))
    }
    $myPGCol += $myPGObj
    }
    }

    $output+= ”
    $output += $Cluster.Name
    $output+= ”
    If ($myDSCol.Count -eq 0)
    {
    $output += ”
    $output += “All datastores OK.”
    $output += ”
    }
    Else
    {
    $output += ”
    $output += Create-HTMLTable $myDSCol
    $output += ”
    }
    If ($myLUNCol.Count -eq 0)
    {
    $output += ”
    $output += ‘All LUNs OK.’
    $output += ”
    }
    Else
    {
    $output += ”
    $output += Create-HTMLTable $myLUNCol
    $output += ”
    }
    If ($myPGCol.Count -eq 0)
    {
    $output += ”
    $output += “All portgroups OK.”
    $output += ”
    }
    Else
    {
    $output += ”
    $output += Create-HTMLTable $myPGCol
    $output += ”
    }

    Clear-Variable VMHosts -ErrorAction SilentlyContinue
    Clear-Variable Datastores -ErrorAction SilentlyContinue
    Clear-Variable DSdiffs -ErrorAction SilentlyContinue
    Clear-Variable PortGroups -ErrorAction SilentlyContinue
    Clear-Variable PGdiffs -ErrorAction SilentlyContinue
    Clear-Variable LUNs -ErrorAction SilentlyContinue
    Clear-Variable LUNdiffs -ErrorAction SilentlyContinue
    }

    #$output += ”
    #$output | Out-File $outputFile -Force
    #ii $outputfile

    #==========================================================================
    $MyReport += $output

    #Disconnect-VIServer -Confirm:$False

    $MyReport += Get-CustomHeader0Close
    $MyReport += Get-CustomHTMLClose

    #Uncomment the following lines to save the htm file in a central location
    #$Date = Get-Date
    #$Filename = “C:\Scripts\” + $VIServer + “DailyReport” + “_” + $Date.Day + “-” + $Date.Month + “-” + $Date.Year + “.htm”
    #$MyReport | out-file -encoding ASCII -filepath $Filename
    #Invoke-Item $Filename

    send-SMTPmail $EmailTo $EmailFrom “$VISRV Daily Report” $SMTPSRV $MyReport

    $VIServer | Disconnect-VIServer -Confirm:$false

  46. This is a stupid question but I am new to PS.
    How to run this program.
    I get the following errors
    ###################################################################################
    C:\>C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “e:
    \Program Files\VMware\Infrastructure\vSphere PowerCLI\vim.psc1 ” & “C:\Scripts\D
    ailyReport.ps1 10.10.1.176
    Windows PowerShell console file “”e:\Program” extension is not psc1. Windows Pow
    erShell console file extension must be psc1.
    The filename, directory name, or volume label syntax is incorrect.
    ###################################################################################
    If I run it from PS console
    PS C:\Documents and Settings\athevend\My Documents\Downloads> powershell.exe Dai
    lyReport.ps1 10.10.1.172
    The term ‘DailyReport.ps1′ is not recognized as a cmdlet, function, operable pr
    ogram, or script file. Verify the term and try again.
    At line:1 char:16
    + DailyReport.ps1 <<<< 10.10.1.172
    ####################################################

  47. Alan,

    This is a stupid question but I am new to PS.
    How to run this program.
    I get the following errors
    ###################################################################################
    C:\>C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “e:
    \Program Files\VMware\Infrastructure\vSphere PowerCLI\vim.psc1 ” & “C:\Scripts\D
    ailyReport.ps1 10.10.1.176
    Windows PowerShell console file “”e:\Program” extension is not psc1. Windows Pow
    erShell console file extension must be psc1.
    The filename, directory name, or volume label syntax is incorrect.
    ###################################################################################
    If I run it from PS console
    PS C:\Documents and Settings\athevend\My Documents\Downloads> powershell.exe Dai
    lyReport.ps1 10.10.1.172
    The term ‘DailyReport.ps1′ is not recognized as a cmdlet, function, operable pr
    ogram, or script file. Verify the term and try again.
    At line:1 char:16
    + DailyReport.ps1 <<<< 10.10.1.172
    ####################################################

  48. @RobVM

    Another note, on this test system, when I added a second VM, the number of VMs show in the report (2), but it is still missing the cluster (a single cluster). I’m guessing the (($VM).Count) only works if there is more than one, same for the cluster. Maybe a bug in PowerCLI?

  49. Al,

    This is a stupid question but I am new to PS.

    How to run this program.

    I get the following errors

    ###################################################################################
    C:\>C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “e:
    \Program Files\VMware\Infrastructure\vSphere PowerCLI\vim.psc1 ” & “C:\Scripts\D
    ailyReport.ps1 10.10.1.176
    Windows PowerShell console file “”e:\Program” extension is not psc1. Windows Pow
    erShell console file extension must be psc1.
    The filename, directory name, or volume label syntax is incorrect.

    ###################################################################################

    If I run it from PS console

    PS C:\Documents and Settings\athevend\My Documents\Downloads> powershell.exe Dai
    lyReport.ps1 10.10.1.172
    The term ‘DailyReport.ps1’ is not recognized as a cmdlet, function, operable pr
    ogram, or script file. Verify the term and try again.
    At line:1 char:16
    + DailyReport.ps1 <<<< 10.10.1.172

    ###################################################################################

  50. Hi, I just found a little bug with the “No VM tools” check. Since you only check if the version is equal 0 you don’t get VMs without tools and those who don’t report the version number correctly (e.g. Netware 6.5)
    I modified the script. It now checks the “Guest.ToolsStatus” value and reports every VM which is not equal to “toolsOK”.
    You now get every VM with the status “toolsOld” or “toolsNotInstalled”.
    # —- No VM Tools —-
    $NoTools = $FullVM | Where { $_.Runtime.PowerState -eq “poweredOn” } | Select Name, @{N=”Tools”; E={$_.Guest.ToolsStatus}} | Where {$_.Tools -ne “toolsOK”} |

    Select Name, @{N=”Status”; E={$_.Tools}}
    If (($NoTools | Measure-Object).count -gt 0) {
    $MyReport += Get-CustomHeader “1” “VMware Tools”
    $MyReport += Get-HTMLTable $NoTools
    $MyReport += Get-CustomHeaderClose
    }

    hope it helps

  51. Nice script.
    How about to add a check on the VM hardware version. Comes in handy for those of us who gonna upgrade to vSphere in the next time.
    With this line one would get every VM with the old hardware version.
    Get-View -ViewType VirtualMachine | Where { $_.Runtime.PowerState -eq “poweredOn” } | Select Name, @{N=”VMVersion”; E={$_.Config.Version}} | Where {$_.VMVersion -eq “vmx-04”} | Select Name

    It should be an optional switch, because in a VI3 environment it would “destroy” the report.

    greetings Killsystem

  52. The latest version of the script is running without errors, however the Number of VMs and Clusters are both empty. The report does show the number of hosts and datastores correctly, and the state of all the services.

  53. This script works great. I was wondering if anyone has tried to add the disk space usage of the actual VMs. I have tried using several examples from the PowerCli communities but have not had much luck. I can seem to pipe the Get-VM to the Get-VMGuest without getting an error “Strings as pipeline input are not supported”

  54. What’d be perfect would be a listing of the VMFS (+ the host’s partitions??) volumes too! Can’t be too hard I might take a look…

  55. Erm, Matt, if you look more closely you will see that it states “Any VMs which have CD-Rom or Floppy Drive’s connected”. So I think you’re covered.

    I wanted to say thank you, actually, for adding that check as it was on my wish list.

  56. Thanks for a great script!
    I upgraded from VI Toolkit 1.5 to vSphere PowerCLI 4.0 – this causes the path/command to be slightly different. I also had a problem with the single/double quotes. Here’s what worked for me:

    C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files\VMware\Infrastructure\VIToolkitForWindows\vim.psc1” “& ‘C:\Scripts\DailyReport.ps1’ TESTVC01”

  57. Al, another great script.

    Idea – Is it possible to include a section for hardware changes, including the person who did it?

  58. Great Script, just one remark, the variables $VM $Clusters etc. should be declared as [System.Array]$Clusters because if there is only one Item found the method $clusters.count will not return anything.

  59. @James
    I suggest using this for the check instead.

    get-vm | where { $_.PowerState -eq “PoweredOn” } | Get-VMGuest | where { $_.State -ne “Running” } | select vmName, State

  60. @bob
    All set. Stupid user tricks. I was thinking the line the the script for my vc was all I needed. I still had to run the command and put the vcname at the end

  61. Can you help me with a couple of points
    (a)Can you advise on a tool to create the crd file?

    (b) I was able run the script interactively, however the email I received did not have the complete contents. In the main body I got:
    General Details
    Number of Hosts:
    Number of VMs:
    Number of Clusters:
    Number of Datastores:

    Service Details
    Name State StartMode Health
    VMware Capacity Planner Service Running Auto OK

    VMware License Server Running Auto OK
    VMware Update Manager Service Running Auto OK
    VMware VirtualCenter Server Running Auto OK
    VMware Infrastructure Web Access Running Auto OK

  62. I have been trying unsuccesfully to the this to run. I have tried against a specific esx server and against my vcenter server 2.5 U4.

    I get nothing when I try to run this now. First I got the Get-VIserver error. I upgraded to the latest vitool kit. Now I get no response at all. What am I missing here.

  63. One more suggestion – how about listing out virtual machines that have CD-ROM or floppy images attached and connected?

  64. heys really nice script … I seem to be getting errors
    Get-WmiObject : Access is denied <exception from HRESULT: 0x80070005 >

  65. My first thought was, has he been copying me? No not really, just that I have been working on something very similar over the last few weeks, however instead of each report portion being a function as you have here, I have them as separate ps1 files. I have a scheduled task that looks for all the ps1 files in a directory, eg c:\reporting\daily\ and runs them. In this way I can add a new report, replace or remove any given report just by moving the files around. One benefit I have found, since I am only new to powershell, by doing this is if I mess up one of the reports for some reason, a typo, then all my other reports still execute correctly.
    I love seeing different ways other people come up with to accomplish the same tasks, great work. 🙂

  66. Thank you for your script! It works well, except for the error below. Any ideas why this occurs? -Jonathan

    Attempted to divide by zero.
    At C:\Program Files\VMware\Infrastructure\VIToolkitForWindows\Scripts\DailyReport.ps1:262 char:74
    + $MyDetails.PercFreeSpace = [math]::Round(((100 * ($ds.FreeSpaceMB)) / <<<< ($ds.CapacityMB)),0)
    + CategoryInfo : NotSpecified: (:) [], RuntimeException
    + FullyQualifiedErrorId : RuntimeException

  67. Great script Alan,

    Can I suggest to sort-object VMs collection and Hosts collection in the next version just to have them ordered in the report?

  68. Hi, great script!

    Any chance for the next version to have ability to select which cluster(s) you wish to report on? ie. I have a vCentre installation which covers Dev/Test and Production so I’d just like to daily report on the Production clusters and not Dev/Test.

    Many thanks.

  69. Great Script…. Works wonderfully!

    My only feedback is that the “No VMTools” section displays any VM’s that are not ‘OK’ so even ones with Tools installed, but outdated get reported.

  70. @David Strebel
    sounds like the account you are using to run the script does not have admin credentials on rhetorical vc server, gouging will need to specify the user acount as described above

  71. Keep getting the following error:

    Get-WmiObject : User credentials cannot be used for local connections
    At C:\psscripts\VMwareDailyReport.ps1:187 char:28
    + $Services = get-wmiobject <<<< win32_service -Credential $creds -Com
    puterName $VISRV | Where {$_.DisplayName -like "VMware*" }
    Get-WmiObject : User credentials cannot be used for local connections
    At C:\psscripts\VMwareDailyReport.ps1:511 char:28

  72. First off, I must say this is a great script! It’s essentially the reason I finally got around to installing powershell.

    I do have a suggestion of another piece of info that would be nice to see (if possible). I’d like to see the number of DRS migrations that happened over the day.

    Cheers,

  73. Wow,

    This is really a nice script, i was wondering if you can build in the following two options:
    – Number of active VM’s
    – Number of inactive VM’s

    For the rest the script is perfect, going to run this once a week to make a nice status report 🙂

  74. Hey Alan,

    First of all I must say this script will be great if it works. I keep on getting an error on loading it. See the details below. Maybe you know how to fix this.

    Thanks in advance

    Select-Object : You cannot call a method on a null-valued expression.
    At C:\Scripts\VMwareDR.ps1:297 char:21
    + $mySnaps | Select <<<< VM, Name, @{N="DaysOld";E={((Get-Date) –
    $_.Created).Days}}, @{N="Creator";E={(Find-Username (($_.Creator.split("\"))[1]
    )).Properties.displayname}}, Created, Description | Sort DaysOld

  75. @Gerald Schneider
    That sounds like when it is trying to lookup the username in Active Directory, is the machine you are running the script on a member of the domain ? Also is the user you are using to run the script a member of the domain ?

    I will have to add a trap so it at least continues, sorry about that. Keep an eye out for version 1.13 !

  76. Alan, as always superb work. Have run this today and sent on to our Operations Manager who has been talking about getting some scheduled reporting setup. I’m awaiting his feedback but I think he’ll like it.

    Keep up the good work Al, will stick a blog post up about it as well as this should definately be shared!

  77. Very nice script. I’d love to use it daily, but it stops in the middle with an exception and only sends a partly email. The exception looks like this:

    Select-Object : Exception calling “FindOne” with “0” argument(s): “The specified domain either does not exist or could not be contacted.”

    Our environment is a vSphere Server, but the hosts aren’t updated to version 4 yet. Could that be a problem?

  78. @Virtu-Al
    OK, LucD helped me narrow this down, it looks like the MoRef.Value changes when the VC is upgraded, apparently the VCB documentation says it could change after a restart to the VC service but this will need testing. I don’t understand why VMware change this as it is supposed to be unique. I will try and get this confirmed.

  79. @Virtu-Al
    I recently (yesterday actually) upgraded my entire environment to vSphere 4. All of the snapshots were taken when the environment was running VI3. All snapshots were taken by users and not some 3rd party application or process so it should be in there. I’ll do some testing to see what happens with new snapshots created in vSphere.

  80. @John
    No dumb questions here John, this script takes the name of the server as a parameter, as written above you can run this script by calling it with the name of your VC server after as below:

    C:\WINDOWS\system32\windowspowershell\v1.0\powershell.exe -PSConsoleFile “C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\vim.psc1″ ” & “C:\Scripts\DailyReport.ps1 TESTVC01″

  81. OK, this is dumb question but…

    Where am I specifying my VC server in the script? I have tried a couple different things but I am not getting anywhere. I may start this as a scheduled task but wanted to test things first. I am trying to learn this stuff and this is way beyond the one-liners I have been using. What am I missing?

  82. Alan – The new version did indeed stop the error from showing up, but I still don’t see a “Creator” field in the Snapshot portion of the output. Any thoughts on that?

  83. Awesome script, you always deliver great stuff. I ran the script and like a poster above it works but throws the following error:

    Select-Object : You cannot call a method on a null-valued expression.
    At C:\Scripts\Healthcheck.ps1:297 char:21
    + $mySnaps | Select <<<< VM, Name, @{N="DaysOld";E={((Get-Date) –
    $_.Created).Days}}, @{N="Creator";E={(Find-Username (($_.Creator.split("\"))[1]
    )).Properties.displayname}}, Created, Description | Sort DaysOld

    It looks like it is failing on the Find-Username bit, since "Creator" is not listed under the Snapshots section in the report. Any thoughts?

  84. Hi Alan,

    I’ve ran your script and it completes ok but throws me an error. I think its complaining about a consolodated helper snapshot (maybe because it doesn’t have a creator?)

    Select-Object : You cannot call a method on a null-valued expression.
    At C:\scripts\VMwareDailyReport.ps1:324 char:21
    + $mySnaps | Select <<<< VM, Name, @{N="DaysOld";E={((Get-Date) – $_.Created).Days}}, @{N="Creator";E={(Find-Username (($_.Creator.split("\"))[1])
    ).Properties.displayname}}, Created, Description | Sort DaysOld
    + CategoryInfo : InvalidResult: (Consolidate Helper- 0:PSObject) [Select-Object], RuntimeException
    + FullyQualifiedErrorId : PropertyEvaluationNoExpand,Microsoft.PowerShell.Commands.SelectObjectCommand

  85. That is definately a script I would like to use, great! Unfortunately I get this error message:

    Missing condition in switch statement clause.
    At :line:63 char:1
    + – <<<< smtpserver {$smtpserver = $args[$i+1]}

  86. Send me an email I wrote one very similar to yours that Id like to share with you. ofcourse yours is nicer 😉

Leave a Reply