PowerCLI: Daily Report V2

Firstly I would like to thank everyone who took the time to comment on my previous Daily Report script, I really appreciate the feedback and have never had so many comments !

Now onto V2…

This one will take a while longer to run than the last script but as its a scheduled task we are not really worried about that, we are hardly going to sit there and watch it running !

I think you will agree the results are worth the wait:

What’s new

  • Bug Fixes
  • Active VMs count
  • Inactive VMs count
  • DRS Migrations count and list
  • Correct NTP Server check for each host
  • VMs stored on local datastores
  • NTP Service check for each host
  • vmkernel warning messages for each host
  • VM CPU ready over x%
Bug Fixes

I have fixed the bugs which were mentioned in my previous posts comments, thanks to all for helping me find these.  I have also added a few other tweaks along the way to improve output etc.

Active VMs count

image

In the General Details section there will now be a count of the number of VMs which are powered on.

Inactive VMs count

image

In the General Details section there will now be a count of the number of VMs which are powered off.

DRS Migrations count and list

image

In the General Details section there will now be a count of the number of DRS migrations over the given timescale (configurable in the config section), these migrations will also be listed in the DRS Migrations section later in the report:

image

Correct NTP Server and service check for each host

In the config section of the script you must specify your correct ntp server name, the script will then check to make sure all your hosts are using this NTP server and that the NTP service is running, if they are not it will report on these as below:

image

VMs stored on local datastores

The script will check to see if you have any VMs which reside on local storage if they do it will report these.  At the top of the script you can add exclusions for things like templates or machines you know are allowed to be on local storage.

image

vmkernel warning messages for each host

Each host’s vmkernel log file will be checked and if any warning messages are being displayed these will be included in the report:

image

VM CPU ready over x%

Any VMs with a CPU %RDY over the configurable amount will be displayed in the report as below:

image

I hope you enjoy these additions and find them as useful as I do.

Please leave your comments below !

Check out the latest version here

Alan

Alan Renouf has a role of Automation Frameworks Product Manager at VMware responsible for providing the architects and operators of the cloud infrastructure with the toolkits/frameworks and command-line interfaces they require to build a fully automated software-defined datacenter. Alan is a frequent blogger at http://blogs.vmware.com/vipowershell and has a personal blog at http://virtu-al.net. You can follow Alan on twitter as @alanrenouf.

You may also like...

123 Responses

  1. Ian Martin says:

    Is there something similar to this for the VMWare View PowerCLI and View environment or will this work for it as well?

  2. Chris says:

    This looks a great script but doesn’t quite work for me. It generates a report but two errors come up as well which make me suspect I’m missing at least part of the report. The errors are as follows. I first installed vSphere PowerCLI 4.0.1 which I guessed was the right thing; the script doesn’t document its software dependencies.

    Get-WmiObject : Access denied
    At C:\ps\DailyReportV2.ps1:203 char:28
    + $Services = get-wmiobject <<<< win32_service -ComputerName $VISRV |
    Where {$_.DisplayName -like "VMware*" }
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

    Get-WmiObject : Access denied
    At C:\ps\DailyReportV2.ps1:633 char:28
    + $ErrLogs = Get-WmiObject <<<='” + $ConvDate +
    “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=”TimeGenerated”;E={$_.
    ConvertToDateTime($_.TimeGenerated)}}, Message
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

    Get-WmiObject : Access denied
    At C:\ps\DailyReportV2.ps1:647 char:29
    + $WarnLogs = Get-WmiObject <<<='” + $ConvDat
    e + “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=”TimeGenerated”;E={
    $_.ConvertToDateTime($_.TimeGenerated)}}, Message
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

  3. Adrian says:

    I really like this script.. Thanks for putting the work into it, now if I can combine the two other VC’s we have into the single report that would be good (we have a vc for 2.5, 3.0, and 3.5) – no really good technical reason for it at the moment.
    Thanks again

  4. Jamie Lotz says:

    When I run this I’m getting:

    WARNING: There were one or more problems with the server certificate:
    * A certification chain processed correctly, but terminated in a root certificate which isn’t trusted by the trust
    provider.
    * The certificate’s CN name does not match the passed value.

    “Check Host Certificates” is unchecked in vCenter. Any ideas?

  5. grannysmyth says:

    I was able to get the script scheduled in Task Scheduler…

  6. grannysmyth says:

    I have one other question if you don’t mind. I am able to run the script from the command line using the following command:
    [vSphere PowerCLI] C:\scripts> .\vcheckv3.ps1 vmonster
    How do I schedule this in task manager? Power CLI is installed @
    “C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\”

    Thanks!

  7. grannysmyth says:

    Great Script! Most everything is working except for when the script checks for created or cloned VM’s. I get the following error: Any ideas?

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

    At C:\Temp\vcheckv3.ps1:625 char:188
    + $OutputCreatedVMs = @($VIEvent | where {$_.Gettype().Name -eq “Vm
    CreatedEvent” -or $_.Gettype().Name -eq “VmBeingClonedEvent” -or $_.Gettype().N
    ame -eq “VmBeingDeployedEvent”} | Select <<<< createdTime, @{N="User";E={(Find
    -Username (($_.userName.split("\"))[1])).Properties.displayname}}, fullFormatte
    dMessage)
    Select-Object : Exception calling "FindOne" with "0" argument(s): "The specifie
    d domain either does not exist or could not be contacted.
    "
    At C:\Temp\vcheckv3.ps1:625 char:188
    + $OutputCreatedVMs = @($VIEvent | where {$_.Gettype().Name -eq "Vm
    CreatedEvent" -or $_.Gettype().Name -eq "VmBeingClonedEvent" -or $_.Gettype().N
    ame -eq "VmBeingDeployedEvent"} | Select <<<< createdTime, @{N="User";E={(Find
    -Username (($_.userName.split("\"))[1])).Properties.displayname}}, fullFormatte
    dMessage)
    Select-Object : Exception calling "FindOne" with "0" argument(s): "The specifie
    d domain either does not exist or could not be contacted.
    "
    At C:\Temp\vcheckv3.ps1:625 char:188
    + $OutputCreatedVMs = @($VIEvent | where {$_.Gettype().Name -eq "Vm
    CreatedEvent" -or $_.Gettype().Name -eq "VmBeingClonedEvent" -or $_.Gettype().N
    ame -eq "VmBeingDeployedEvent"} | Select <<<< createdTime, @{N="User";E={(Find
    -Username (($_.userName.split("\"))[1])).Properties.displayname}}, fullFormatte
    dMessage)

  8. kevin says:

    Supply values for the following parameters:
    Credential
    Get-WmiObject : User credentials cannot be used for local connections
    At C:\code\VMware_Daily_Report.ps1:201 char:28
    + $Services = get-wmiobject <<<< win32_service -Credential $creds -Com
    puterName $VISRV | Where {$_.DisplayName -like "VMware*" }
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

    Get-WmiObject : User credentials cannot be used for local connections
    At C:\code\VMware_Daily_Report.ps1:631 char:28
    + $ErrLogs = Get-WmiObject <<<='” + $ConvDate + “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=”Ti
    meGenerated”;E={$_.ConvertToDateTime($_.TimeGenerated)}}, Message
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

    Get-WmiObject : User credentials cannot be used for local connections
    At C:\code\VMware_Daily_Report.ps1:645 char:29
    + $WarnLogs = Get-WmiObject <<<='” + $ConvDate + “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=
    “TimeGenerated”;E={$_.ConvertToDateTime($_.TimeGenerated)}}, Message
    + CategoryInfo : InvalidOperation: (:) [Get-WmiObject], Managemen
    tException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.C
    ommands.GetWmiObjectCommand

  9. Rob says:

    @Marshall
    I’ve got the same error. I also ran this (and also vCheck 3) script on VC 4.0 with ESX 3.5 and 4.0 hosts. When vCheck 3 starts with “..Checking Snapshots” the VMware Virtual Center service crashed. I tried a few times but the error stil exist. Now with vCheck its possible to disable some checks, so I disabled the Snapshot part and the script works fine.
    Does somebody know why the Virtual Center service crashed during the Snapshot report? When I run a Get-VM | Get-Snapshot i’ve got no problems

    Exception calling “ReadNextTasks” with “1” argument(s): “There is an error in X
    ML document (7, 203404).”
    At C:\Beheer\scripts\vCheck\vCheck3.0.ps1:420 char:45
    + $collection = $collectionImpl.ReadNextTasks( <<<< $tasknumber)
    Exception calling "DestroyCollector" with "0" argument(s): "The remote server r
    eturned an error: (502) Bad Gateway."
    At C:\Beheer\scripts\vCheck\vCheck3.0.ps1:436 char:34
    + $collectionImpl.DestroyCollector( <<<< )

  10. leeon says:

    hi,

    Really appreciate the efforts you took in developing this script. Can you please help me identifying why I am getting the below error .I am running this script form the vesi .

    Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))
    At :line:203 char:27
    + $Services = get-wmiobject <<<< win32_service -ComputerName $VISRV | Where {$_.DisplayName -like "VMware*" }

  11. Ben says:

    Hi Al, Great script..

    I’m seeing this error:
    Get-Stat : 4/11/2009 10:31:58 AM Get-Stat The metric counter “cpu.rea
    dy.summation” doesn’t exist for entity “My Server”.
    + $myObj.PercReady = [Math]::Round((($v | Get-Stat <<<< -Stat
    Cpu.Ready.Summation -RealTime | Where {$_.Instance -eq $cpunum} | Measure-Objec
    t -Property Value -Average).Average)/200,1)
    Get-Stat : 4/11/2009 10:32:30 AM Get-Stat The metric counter "cpu.rea
    dy.summation" doesn't exist for entity "AnotherServer".

    Only happening with 3-4 of our servers out of 300, so just wondering if it may be a data collection timeout issue?

  12. Virtu-Al says:

    @Hase3d
    One thing we have done here is create an exchange group to send it to, you should also be able to add a ; between each email address.

  13. Virtu-Al says:

    @Robert-NL
    Thanks, unfortunatly i do not have a 3.02 host and dont think this cmdlet works agains that version. Sorry

  14. Hase3d says:

    Hello, really nice script. Works like a charm except that I am having trouble to with the $EmailTo = “” I would like to have multiple mail recipiants but I get allot of errors when adding more mail adresses to that line? If I want to have more than 1 mail recipiant how should the line look?

  15. Robert-NL says:

    In the line of code:
    $NTPCheck = @(Get-VMHost | Select Name, @{N=”NTPServer”;E={$_ | Get-VMHostNtpServer}}, @{N=”ServiceRunning”;E={(Get-VmHostService -VMHost $_ | Where-Object {$_.key -eq “ntpd”}).Running}} | Where {$_.ServiceRunning -eq $false -or $_.NTPServer -ne $ntpserver})

    Get-VMHostNtpServer gives the error: “Index was outside the bounds of the array”
    on a VMware ESX Server version 3.0.2.

    I have not found a solution yet, but I wanted you to know about the problem.

  16. Robert-NL says:

    If there are no local storage VMs ($LocalOnly is empty) I get an error on the next line:
    $LocalVMs = @($LocalOnly | Get-VM | Where { $_.Name -notmatch $LVMDoNotInclude } |Get-View | Select Name, @{N=”VMX”;E={$_.Summary.Config.VmPathName}})

    So I changed the code to:

    # —- Local Storage VMs —-
    If ($LocalOnly) {
    $LocalVMs = @($LocalOnly | Get-VM | Where { $_.Name -notmatch $LVMDoNotInclude } |Get-View | Select Name, @{N=”VMX”;E={$_.Summary.Config.VmPathName}})
    If (($LocalVMs | Measure-Object).count -gt 0) {
    $MyReport += Get-CustomHeader “1” “VMs stored on local datastores”
    $MyReport += Get-HTMLTable $LocalVMs
    $MyReport += Get-CustomHeaderClose
    }
    }

  17. Robert-NL says:

    @Mike

    Thanks Mike for the code.

    I just learned that PowerState can also be Suspended. So I added the next line of code after In-active VMs:
    $MyReport += Get-HTMLDetail “Suspended VMs:” (@($FullVM | Where { $_.Runtime.PowerState -eq “Suspended” }).Count)

  18. Jonathan Jewett says:

    @Jonathan Jewett
    Sorry, I missed Alan’s comment earlier in the tread acknowledging the bug.

  19. Jonathan Jewett says:

    I think your Daily Report script is great! I do get the exception error below because a couple of SAN luns are very low on disk space:

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

  20. Christopher Petro says:

    Actually, I lied.

    It isn’t gathering everything from the local machine, it’s not getting the logs from the local virtual center server, but it is from the remote servers.

  21. Christopher Petro says:

    One thing you may want to advertise or publish somehow.

    In my environment I needed to make this modification:

    Original:
    $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
    $msg.IsBodyHTML = $true
    $mailer.send($msg)

    New:
    $msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
    $msg.IsBodyHTML = $true
    $mailer.Credentials = [system.Net.CredentialCache]::DefaultNetworkCredentials
    $mailer.send($msg)

    Because my smtp server required authentication.

    I also get authentication errors:
    Get-WmiObject : User credentials cannot be used for local connections
    At E:\PowershellScripts\dailyReports\DailyReportV2.ps1:204 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 E:\PowershellScripts\dailyReports\DailyReportV2.ps1:634 char:28
    + $ErrLogs = Get-WmiObject <<<='” + $ConvDate + “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=”Ti
    meGenerated”;E={$_.ConvertToDateTime($_.TimeGenerated)}}, Message
    Get-WmiObject : User credentials cannot be used for local connections
    At E:\PowershellScripts\dailyReports\DailyReportV2.ps1:648 char:29
    + $WarnLogs = Get-WmiObject <<<='” + $ConvDate + “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=
    “TimeGenerated”;E={$_.ConvertToDateTime($_.TimeGenerated)}}, Message

    when scanning the local host (this is regardless of the permissions of the “user”) or when scanning remote hosts (I have 30 virtual centers under my management, most with 2-5 hosts attached). I don’t worry too much about these errors because they aren’t the output I’m most interested in.

  22. Marshall says:

    @Virtu-Al Yes, the GUI is working just fine. I would LOVE to use this report if it didn’t disconnect my network connectivity to vcenter :(

  23. Virtu-Al says:

    @ZOMAN
    Thanks for the nice comment, keep an eye on my blog over the next couple of days…Shhhh !

  24. ZOMAN says:

    First off THANK YOU THANK YOU THANK YOU for this wonderful report. I noticed in your other post that you were considering adding CPU and Memory utilization and maybe some other features are you still considering? I will take any update you have to this script as I know it will blow me away or can you help me with adding that info CPU, MEM, Network, DISK, avg utilization or something similar

  25. Virtu-Al says:

    @Marshall
    I have never seen that before, all this script does is pull the information from the API much like the client does, it looks like an issue when its pulling the tasks, im guessing the GUI is ok when you click on your datacenter and then tasks & events tab ?

  26. Marshall says:

    I ran this script on VI 4.0 with ESX 3.5 hosts and was immediately disconnected from my VI client and received error:

    Exception calling “ReadNextTasks” with “1” argument(s): “Unable to read data from the transport connection: An existing
    connection was forcibly closed by the remote host.”
    At C:\Program Files\VMware\Infrastructure\VIToolkitForWindows\scripts\DailyReportV2.ps1:352 char:45
    + $collection = $collectionImpl.ReadNextTasks <<<< ($tasknumber)
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

    I had to reboot vcenter to regain network connectivity. I waited and tried it again after business hrs and it did the same thing… any idea what may have happened?

  27. Virtu-Al says:

    @bitsorbytes
    Very soon, I just need to find time to put the final touches on, im going to leave some stuff till V4 as I already have lots of new features to add, thanks to all who have sent them through !

  28. Virtu-Al says:

    @Chad
    Very strange, can you log into your VC over RDP using the same account and look at the services ?

  29. bitsorbytes says:

    @Virtu-Al

    No pressure, but any ideas when the next version will be released?

  30. Chad says:

    @Virtu-Al
    That’s what has me stumped. The two accounts I tested with are full admins on the virtual center server.

    I’ll keep looking.

    Thanks

    Chad

  31. Virtu-Al says:

    @Marcel
    It can be run on the VC server but you will need powershell and powercli installed, it can basically run anywhere you have powercli and powershell installed.

    I am confused by your feature request, this already exists and was actually the first thing I put in there, unless I am missing something !

  32. Virtu-Al says:

    @Chad

    @Marcel

    There are basically two types of data this report looks at:

    1. The Virtual Infrastructure data which it uses PowerCLI and the credentials of the current logged on user, unless you change the connect-viserver statement in the script.

    2. The vCenter Windows data (event logs and services) for which it uses the current logged on user or at the top you can specify domain\username and the next time the script runs you will be asked to input the same domain\username and password which is then stored in an encrypted credentials file for further use by the script.

    It looks like Number 2 is failing for you so you either need to run the script as a user who has access to your vCenter server or use the setting at the top of the script to specify a domain\username that has access.

    Hope this clears things up a little.

  33. Chad says:

    @Marcel

    I’m getting the same Get-WmiObject : Access is denied errors. Tried it with two different admin accounts. Are there additional dependencies to be able to access the event logs?

  34. Marcel says:

    btw, a feature request for the next version :

    Datastore usage rapport :-)

    We currently use this script for it :

    connect-VIServer vc.company.com

    $datum = (get-date -uformat “%D”)
    $emailFrom = “some@domain.com”
    $emailTo = “team@company.com”
    $subject = “LUN Usage rapport ” + $datum
    $smtpServer = “smtp.server.com”

    Get-datastore | Sort-Object FreeSpaceMB -Descending | foreach-object {

    $capacitymb = $_.CapacityMB
    $FreeSpaceMB = $_.FreeSpaceMB
    $UsedSpace = $capacitymb – $freespacemb

    $perc = $UsedSpace / $capacitymb * 100
    $perc = “{0:N1}” -f $perc

    if ($perc -gt 95) {$output += “Datastore ” + $_.Name + ” is for ” + $perc + “% filled“}
    Else {$output += “Datastore ” + $_.Name + ” is for ” + $perc + “% filled”}
    }

    $body = New-Object System.Text.Stringbuilder
    [void] $body.AppendLine(“”);
    foreach ($line in $output){
    [void] $body.AppendLine($line.ToString())
    }
    [void] $body.AppendLine(“”);

    $smtp = new-object Net.Mail.SmtpClient($smtpServer)
    $MailMessage = new-object Net.Mail.MailMessage($emailFrom, $emailTo, $subject, $body.ToString())
    $MailMessage.IsBodyHtml = $true
    $MailMessage.ReplyTo = “some@domain.com”
    $smtp.Send($MailMessage)

    i’ll try to push it in on this version, if i succeed i’ll send you the code.

    cheers!!

  35. Marcel says:

    ah i figured out you can’t run this script on the same server that virtualcenter is installed on… Never mind my previous posting.

  36. Virtu-Al says:

    @Ricardo
    It depends on how big your infrastructure is, it can take 2 mins but can also take over 1hr (my prod env). I am adding some output to the next version just so you know its still doing things !

  37. Ricardo says:

    How long would you expect this script to take to run?

  38. Marcel says:

    Beautifull scripting, extremely usefull.

    However, when i run it i get the following error:

    Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS
    DENIED))
    At D:\Scripts\dailyreport.ps1:203 char:28
    + $Services = get-wmiobject <<<< win32_service -ComputerName $VISRV |
    Where {$_.DisplayName -like "VMware*" }
    Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS
    DENIED))
    At D:\Scripts\dailyreport.ps1:633 char:28
    + $ErrLogs = Get-WmiObject <<<='” + $ConvDate +
    “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=”TimeGenerated”;E={$_.
    ConvertToDateTime($_.TimeGenerated)}}, Message
    Get-WmiObject : Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESS
    DENIED))
    At D:\Scripts\dailyreport.ps1:647 char:29
    + $WarnLogs = Get-WmiObject <<<='” + $ConvDat
    e + “‘”) | Where {$_.Message -like “*VMware*”} | Select @{N=”TimeGenerated”;E={
    $_.ConvertToDateTime($_.TimeGenerated)}}, Message

    Any advice on how to resolve this?

    Thanks!

  39. Virtu-Al says:

    @Barry Coombs
    Thanks Barry, if your at the next UK VMUG you may get a nice suprise for free then, of course there is the beer tab afterwards !

  40. Barry Coombs says:

    Fantastic work Alan, you should do using powershell with Vmware training courses! I’d sign up!

  41. Jswano says:

    Hi,
    Thanks for this daily report. It’s work fine. Is it possible to add the triggered alarm in the report ?
    Regards,

  42. Virtu-Al says:

    @Mike
    Mike, the credentials at the top of the script are only for the WMI calls to the VC server to gain service and event log information. You should be able to run this from an account which has access to your Virtual infrastructure just by running the script with a parameter of the VIServer name. Let me know if you need further help.

  43. Virtu-Al says:

    @Simon Price
    I agree, must have missed that one, thanks very much. Would be interested in seeing some of your scripts, are they available anywhere ?

  44. Simon Price says:

    Can I just make a suggestion – I found it an excellent practice to always define the collection up front. For example, instead of ‘$FullVM = Get-View -ViewType VirtualMachine’ , I always use ‘$FullVM = @(Get-View -ViewType VirtualMachine)’
    With the second method, the basetype will _always_ be an array. Otherwise, if it only contains a single item it generally won’t be a basetype array and functions like .count or | measure-object won’t work correctly.
    The functionality for the datacentre is realatively easy – my scripts use some primal script front end forms to give the user a choice of which datacentre (either a single one or all). The collections objects are then populated by using the -location (or in some cases, -datacenter) parameter.
    Cheers,
    Simon P.

  45. Mike says:

    Virtu-Al, sorry, for the newbie post. I’m having problems running the script. No matter how I run the command, I get the following error. I’ve attempeted to put in the script on line 35 the user id, and I’ve left it blank with the same result.

    “Connect-VIServer : Could not connect using the requested protocol.
    At D:\admin\scripted_reports\DailyReportV2.ps1:399 char:29
    + $VIServer = Connect-VIServer <<<< $VISRV
    Connect-VIServer : Could not connect using the requested protocol.
    At D:\admin\scripted_reports\DailyReportV2.ps1:410 char:30
    + $VIServer = Connect-VIServer <<<< $VISRV"

  46. Virtu-Al says:

    @Rinc
    This was added in V1, did you check the V1 post for a list of features ?

  47. Virtu-Al says:

    @Aaron
    Hmmm, its not written to run against a certain datacenter but could be modified to do so. you should also be able to add a port to the connect-viserver line just add -port 8843 on the end.

  48. Virtu-Al says:

    @mlt
    I will add a section for that. Thanks

  49. Rinc says:

    Hi guys, i love this script and will be implementing it for our admins. I wanted to ask is there any way I could also add report on data stores and % space left. Some of our sites have had close calls with datastores filling up due to admins not keeping an eye on them. Any help would be appreciated as i am a Powershell novice.

    Thank you!

  50. Aaron says:

    One more question for you Alan. As you may remember from a couple of my other posts, one of our vcenter servers has to be connected to on a non-standard port. we use 8843, rather than the standard 443. When i try and put Servername:8843 in the connect to line, it throws an error saying it can’t parse the :.

    thanks for these great scripts

    app

  51. Aaron says:

    Alan,
    I have a question. We have one vCenter installation, and a bunch of Datacenters listed but i want to run one of these reports for each datacenter. How would i go about doing that. I tried running it against a specific ESX server, but it threw a bunch of errors.

    Any help would be greatly appreciated.

    thanks

    app

  52. Chris says:

    @rg
    I have the same issue. You can fix it in this way (not pretty but gets the job done:

    For the $ntpserver variable, quote each server and seperate with commas.
    $ntpserver = “ntpserver1″, “ntpserver2″

    Then change the —- NTP Check —- line to read like so:
    $NTPCheck = @(Get-VMHost | Select Name, @{N=”NTPServer”;E={$_ | Get-VMHostNtpServer}}, @{N=”ServiceRunning”;E={(Get-VmHostService -VMHost $_ | Where-Object {$_.key -eq “ntpd”}).Running}} | Where {$_.ServiceRunning -eq $false -or $_.NTPServer -or $_.NTPServer[0] -ne $ntpserver[0] -or $_.NTPserver[1] -ne $ntpserver[1]})

    continue to add to -or and increment the numbers till all your ntpservers are accounted for.

  53. mlt says:

    Perhaps is it possible to add the following:

    In our environment we make use of a NTP server to synchronize the time on all clients & Servers.
    We don’t want that the option synchronize the time with the ESX server in the VMware tools is enabled.
    We use a script to check if there is a VM configured to sync the time with ESX server. If theres an VM so configurered we disable this option.

    The script is:
    Get-VM | Get-View | ? { $_.Config.Tools.syncTimeWithHost -eq $true }.

  54. mlt says:

    @Virtu-Al
    Great. VMWs on Local disks is not done.

  55. Virtu-Al says:

    @mlt
    Thats a know bug, it will be fixed in the next version but is nothing to worry about, it just means you have no vms on local disk which is a good thing !

  56. Virtu-Al says:

    @Marc
    Thanks for your kind comments, Im talking to the VESI people at the moment about being able to schedule this in their product…watch this space !

    Not sure why the get-stat cmdlet isnt working in your environment, have you tried using the cmdlet to report other stats ?

  57. Virtu-Al says:

    @Mike
    Thanks, cool stuff, thats one for the next version

  58. Virtu-Al says:

    @rg
    I will add this in the next version.

  59. mlt says:

    When running this great script i get the following error:

    Attempted to divide by zero.
    At D:\Vmware_Scripts\Report\Report_check.ps1:283 char:74
    + $MyDetails.PercFreeSpace = [math]::Round(((100 * ($ds.FreeSpaceMB)) / <<<< ($ds.CapacityMB)),0)
    Attempted to divide by zero.
    At D:\Vmware_Scripts\Report\Report_check.ps1:283 char:74
    + $MyDetails.PercFreeSpace = [math]::Round(((100 * ($ds.FreeSpaceMB)) / <<<< ($ds.CapacityMB)),0)

  60. Marc says:

    First let me say V2 of this script is awesome! I love the direction of this thing. It would be really cool if this type of script could be incorporated as a plugin to virtual center or the VESI. Great job Alan!!!

    I get the following error regarding the percready section. It errors out like this on every vm and then just doesnt report the section. Any help on this would be great.

    At F:\PSScripts\VMwareDailyReport\VMwareDailyReport.ps1:615 char:53
    + $myObj.PercReady = [Math]::Round((($v | Get-Stat <<<< -Stat
    Cpu.Ready.Summation -RealTime | Where {$_.Instance -eq $cpunum} | Measure-Objec
    t -Property Value -Average).Average)/200,1)

  61. Mike says:

    @Virtu-Al,
    I noticed that “No VM Tools” report doesn’t work for me.

    I changed

    $NoTools = $FullVM | Where { $_.Runtime.PowerState -eq “poweredOn” } | Select Name, @{N=”ToolsVersion”; E={$_.Config.tools.toolsVersion}} | Where {$_.guest.toolsstatus -eq “toolsNotInstalled” -or $_.guest.toolsstatus -eq “toolsNotRunning”} | Select Name

    to

    $NoTools = $FullVM | Where {$_.Runtime.Powerstate -eq “poweredOn”
    -And ($_.Guest.toolsStatus -eq “toolsNotInstalled” -Or $_.Guest.ToolsStatus -eq
    “toolsNotRunning”)} | Select Name, @{N=”Status”;E={$_.Guest.ToolsStatus}}

    This will display both the name of the VM and the status of the tools.

  62. Mike says:

    @Robert-NL,
    Change the following line (to get rid of the templates in the “Number of VMs” count
    $FullVM = Get-View -ViewType VirtualMachine
    to this
    $FullVM = Get-View -ViewType VirtualMachine | Where {-not $_.Config.Template}
    $VMTmpl = Get-Template

    Also add this line below “In-active VMs:” line

    $MyReport += Get-HTMLDetail “Templates:” (@($VMTmpl).Count)

    This will get you what you are looking for.

  63. rg says:

    So my question is about the ntp server check. I have several ntp servers listed for each ESX host just in case one ntp server is unavailable. It seems the get-vmhostntpserver -vhmost ESXhostname returns an array of ntp servers so in the script for the variable $ntpserver what would you do?

  64. Virtu-Al says:

    @Robert-NL
    Great Idea, didn’t notice that one 😉 Thanks

  65. Robert-NL says:

    Thanks for the nice script. We run it daily as a scheduled task and send the report to all the VMware administrators via e-mail. So first thing in the morning is to check e-mail and read the report.

    One thing I noticed is that in the report the sum of active and in-active VMs is more then the number of VMs:
    Number of Hosts: 16
    Number of VMs: 190
    Number of Clusters: 3
    Number of Datastores: 46
    Active VMs: 134
    In-active VMs: 103

    A little investigation showed that GET-VM (used for number of VMs) retrieves only VMs and not templates, while Get-View -ViewType VirtualMachine (used for active and in-active VMs) retrieves templates also. Maybe something for a next release to split the in-active VMs and the templates. Like this:
    Number of Hosts: 16
    Number of VMs: 190
    Number of Clusters: 3
    Number of Datastores: 46
    Active VMs: 134
    In-active VMs: 56
    Templates: 47

  66. Virtu-Al says:

    @John
    Hmmm, do you think that would be more useful than the vm’s created in the previous x days ? Its easily done but I think I will keep it as it is, Don’t worry though I will do a seperate post showing how to get this info so you can add it easily

  67. Virtu-Al says:

    @ZO-US
    All you have to do is run the script with a space and then the name of your VC server for example… Dailyreport.ps1 testvcserver

    For more info on running this as a scheduled task check here: http://www.virtu-al.net/2009/07/10/running-a-powercli-scheduled-task/

  68. ZO-US says:

    Thanks for this wonderful script I keep getting an message specify VI and I am not sure what it is asking for? Should I run this directly through powershell as you can see I am a little lost …………

  69. John says:

    Great great script man!

    Would it be possible to list the 10 latest deployed vms?

    Keep up the good work!

  70. Chris says:

    you are quite right , it only seems to be failing on certain VM’s

    possibly out of date VMtools installs as those boxes dont seem to be showing stats in vCenter – vmtools service fallen over perhaps ?

    still loving the script a lot though – will have to grab you a beer at the next VMUG :)

  71. Chris says:

    Thanks Mike – I’ll give that a try. The Script still completes , so I assume they are warning messages , but I also dont get any % ready section in the logs.

    got another suggestion for v3 for you – looking at numbers of VM’s per datastore ?

  72. Mike says:

    @Virtu-Al
    VMKernel log pulls data for only about 1/3 of the servers. Perhaps I should change the number of days to pull from default 1 to a higher number just to see if this is working.

    On a separate note, I added output to show amount of time each step takes. There are duplicate Get-VMHost and Get-Datastore commands that can be replaced by an existing variable. That should shave some time off.

    prior to general summary stats: 5.3 seconds
    after general summary stats: 90.4 seconds
    snapshots: 6.5 seconds
    datastores: 0.2 seconds
    hosts in maint. mode: 0.0 seconds
    hosts not responding: 0.0 seconds
    new VMs: 14.8 seconds
    removed VMs: 2.2 seconds
    DRS migrations: 3.3 seconds
    VC errors: 1.7 seconds
    no VM tools: 0.7 seconds
    CDROMs connected: 23.0 seconds
    Floppies connected: 16.4 seconds
    Local storage VMs: 200.1 seconds
    NTP check: 92.1 seconds
    CPU %ready: 1011.0 seconds
    VC details: 0.7 seconds
    VC Event log errors: 2.7 seconds
    VC Event log warnings: 2.3 seconds
    VMkernel log check: 2219.1 seconds
    Total Run time: 61.6 minutes

  73. Mike says:

    @Chris,
    I also get “Not authenticated” error. I get it twice, so I think it has to be issues with some VMs in the environment. Perhaps there are no statistics available for them. Strange error though.
    Add the following just below the “ForEach” line within “CPU %Ready Check” on its own line
    $v.Name
    It will ouput the name of each VM as it’s being checked. The error should follow VM name. Check if there is anything unusual about the VM. I’ll do the same.

    Nothing from this “CPU %Ready Check” section shows up in the report. So I’m not sure if its the problem with the script failing or is my environment clean as far as CPU %Ready.

  74. Mark says:

    Virtu-Al :
    @Mark
    So you think I should give some nice output for if people use it from the console ?

    I run via scheduler 2 times a day (so unattended). But on instances where i noticed some issues, i try to re-run and seeing something is better then blank cmd window :-).

    I agree, Run time is not a concern as this is mainly to run from scheduler.

    Thanks

  75. Virtu-Al says:

    @Chris
    Not sure on that error, will have to look up ‘The session is not authenticated.’ I will see what I can find.

  76. Virtu-Al says:

    @Alec
    Having spoken over email I think we have resolved your issues, hopefully as is fine now 😉

  77. RobSF says:

    @Mike: Your fix for multiple NTP servers works for me! Thank you very much.

  78. RobSF says:

    @Alec: I’m running the v2 script (with a few edits) on two VI 3.5 environments. Specifically, we’re running vCenter 2.5u5 and ESX 3.5u4. And it works great for me!

  79. Chris says:

    Hi Alan, I’m having a few fun an games with the script – seems to crash on the CPU ready section with the following series of errors.

    Get-Stat : 8/24/2009 4:00:10 PM Get-Stat 134072FA-071C-4290-A5A3-42538B38
    4589 The session is not authenticated.
    At E:\Scripts\Daily Reportv2.ps1:611 char:53
    + $myObj.PercReady = [Math]::Round((($v | Get-Stat <<<< -Stat
    Cpu.Ready.Summation -RealTime | Where {$_.Instance -eq $cpunum} | Measure-Objec
    t -Property Value -Average).Average)/200,1)

  80. Alec says:

    Is this ESX4/vSphere specific? I’m drowning in a sea of red text with ESX3/VC2.5

  81. Virtu-Al says:

    @Mike
    Nice one Mark, thanks, I havent had time to look at it yet but hey, thats great !

    I also havent done any performance tweaks, it also takes about 45 mins in our production environment, there are a few performance changes I can make, I may do these in the next version but does it matter that much if its a scheduled task ?

  82. Mike says:

    @Virtu-Al
    Great script. Just the right balance of information to include in a “daily” script without making it too overwhelming.
    Looking forward to the “local storage VMs” resolution.

    I resolved “multiple NTP servers” issue by specifying $ntpserver variable at the top of the script to have servers separated by comma:
    $ntpserver = “clock1.domain.com,clock2.domain.com”

    Note: make sure it doesn’t have any extra spaces (“clock1, clock2″ is not going to work)
    also, in the actual section where the check happens, I modified the following (it’s at the end of that line)

    $_.NTPServer -ne $ntpserver
    to
    [string]::join(“,”,$_.NTPServer) -ne $ntpserver

    This combines array of NTP servers into a single text string of comma-separated list of servers, to match how I typed them into the $ntpserver variable.

    BTW, my script runs for over an hour: 3 Locations, 78 Hosts, 475 VMs, 59 datastores
    I’ll have to code to the script to figure out how long each section takes, as well as the whole script.

  83. Virtu-Al says:

    @vishy
    Im glad its working for you, more than one VC would need some work but if we wait a while you never know what might happen in the next version of PowerCLI they may include something to make this easier.

  84. Virtu-Al says:

    @RobSF
    Hey, leave something for me to wow people in V3 :) I will think about the multipl NTP servers. If you can email me the code I will make sure its the same as what I was using. Thanks for your comments.

  85. Virtu-Al says:

    @Brandon Yap
    Thanks, I think I know what the error is then.

  86. Virtu-Al says:

    @bitsorbytes
    Two NTP servers, why didnt I think of that ! – I will have to test that one.

  87. Virtu-Al says:

    @Mark
    They are some nice additions, I will include those definately.

    I have tried to keep the output away from the console as the script is designed to run as a scheduled task, 10 mins is pretty good, it takes 45 mins on my production cluster !

    So you think I should give some nice output for if people use it from the console ?

    Thanks for your comments and additions.

  88. Virtu-Al says:

    @cxo
    Glad its all working, dont worry about the SSL warning, its just the same one you would normally get from the VIC when starting that without your certificate enabled.

  89. bitsorbytes says:

    My NTP checks isn’t working correctly as I have two listed and this fails. Any ideas on how to get this to work correctly for two ntp servers in the list?

  90. Brandon Yap says:

    @Virtu-Al
    Nope, no VM’s on local storage at all.

  91. vishy says:

    Nice script, tested both on VCMS 2.5 and also on vsphere, works well. Wonder if this script can report on more then two VMware vCenter Server Linked Mode environment

    Cheers,

  92. Mark says:

    @Virtu-Al

    I could not locate your email/contact details, so posting the difference here:

    ### At the beginning
    param([string] $EmailTo, [string] $VISRV)
    $scriptVersion=”2.1 [18-August-2009]”
    $vcServer=viserver.mydomain.com
    if ($VISRV -eq “”){
    $VISRV=$vcServer ### To use default if not given in argument
    }
    $to_email=myself@mydomain.com
    if ($EmailTo -eq “”){
    $EmailTo=$to_email ### To use default if not given in argument
    }
    $stDate=Get-Date ## To store script beginning time
    ### Following is to add the snap-in if not already loaded
    ##################
    # Add VI-toolkit #
    ##################
    if ( !(Get-PSSnapin VMWare.VimAutomation.Core -ErrorAction silentlyContinue )) {
    Add-PSsnapin VMware.VimAutomation.Core
    }
    ### Since it now runs over 10 minutes on V2, some nice screen to display
    clear
    write-host “VMWare Daily Report – $scriptVersion” -foregroundcolor DarkBlue -backgroundColor DarkCyan
    write-host “Started on : ” -nonewline -backgroundColor DarkCyan; write-host $stDate -foregroundcolor white -backgroundColor DarkCyan
    write-host “VI-Server : ” -nonewline -backgroundColor DarkCyan; write-host $VISRV -foregroundcolor white -backgroundColor DarkCyan
    write-host “Email to : ” -nonewline -backgroundColor DarkCyan; write-host $EmailTo -foregroundcolor white -backgroundColor DarkCyan
    ….
    ….
    ### Following code is for servers that dont use C:\ for profiles
    $USER = $env:username
    $APPPATH = $env:userprofile + “\” + $USER + “\Application Data”
    #SET THE APPDATA ENVIRONMENT WHEN NEEDED
    if ($env:appdata -eq $null -or $env:appdata -eq 0)
    {
    $env:appdata = $APPPATH
    }
    $VIServer = Connect-VIServer $VISRV
    ….
    ….
    ### I would like to know the running user/script version on the report
    Report created on $(Get-Date)[Script Version : $scriptVersion Run by user : $ENV:user ]
    ….
    ….
    ### Following bit included to know how many windows and how many Linux we got
    $windowsVM= ” ” + (@($FullVM | Where { $_.Guest.GuestFamily -eq “windowsGuest” }).Count) + ” [Powered off: ” + (@($FullVM | Where { $_.Runtime.PowerState -eq “poweredOff” -and $_.Guest.GuestFamily -eq “windowsGuest” }).Count) + “]”
    $linuxVM= ” ” + (@($FullVM | Where { $_.Guest.GuestFamily -eq “linuxGuest” }).Count) + ” [Powered off: ” + (@($FullVM | Where { $_.Runtime.PowerState -eq “poweredOff” -and $_.Guest.GuestFamily -eq “linuxGuest” }).Count) + “]”
    $MyReport += Get-HTMLDetail “Windows VMs:” $windowsVM
    $MyReport += Get-HTMLDetail “Linux VMs:” $linuxVM

    ….
    ….
    ### At the end
    $runTime=[Math]::Round(($(Get-Date) – $stDate).totalseconds)
    send-SMTPmail $EmailTo $EmailFrom “VMWare VIServer $VISRV [Report Runtime $runTime seconds]” $SMTPSRV $MyReport

    If you provide some contact, i can email you the complete code. Thank you.

  93. RobSF says:

    Great script, Al! Thanks so much for contributing it to the community.

    I’m having trouble with the NTP server check. All of our ESX hosts are configured with multiple NTP servers:
    0.us.pool.ntp.org
    1.us.pool.ntp.org
    2.us.pool.ntp.org
    3.us.pool.ntp.org

    How do I check for that with your script?

    Also, I hacked it up a bit to provide CPU and Memory Usage over the last week. If you’re interested, I’ll email you the code I used. And if you have any tips on how to do it better, I’m open to advice!

  94. cxo says:

    @Virtu-Al
    downloaded newest things and all is happy again! NTP checking works and “removed” VMs history goes back more than 1 day.
    Still have the issue when logging on and we do not have SSL certificates set up so I have to assume connections work (same with PowerGUI, for example), but all works anyway.

  95. Virtu-Al says:

    @cxo
    Dont apologise, I couldnt tell you a thing about bash !

    Im just glad I am slowly converting you to PowerCLI and PowerShell !

  96. cxo says:

    Virtu-Al :
    @cxo
    The best thing to do is type get-vicommand from the powercli prompt and see if it has get-vmhostntpserver in the list.

    Thanks for the tip. I indeed do not have that in the list. I am a rather good bash shell guy, just ignorant with Windows, hence the many questions.

  97. Virtu-Al says:

    @cxo
    The best thing to do is type get-vicommand from the powercli prompt and see if it has get-vmhostntpserver in the list.

  98. cxo says:

    @Virtu-Al
    no, I am running a slightly older version. If that is the issue here, I will investigate upgrading as appropriate. Thanks for the feedback.

  99. Virtu-Al says:

    @cxo
    Do you have the latest version of powercli installed ? Sounds like your missing a cmdlet there with get-vmhostntpserver. I will sort the names, well spotted.

    The VMs Removed and Added both use the same number so should be ok, certainly works for me.

    I will put a fix for the error on the local stored vms bit.

    Thanks for your comments !

  100. cxo says:

    @Virtu-Al

    Virtu-Al :
    @Brandon Yap
    I will look into that one, do you have any vms on local storage ?

    FYI… I see this issue as well. No local storage VMs here (at least not at the moment)

  101. cxo says:

    Simply great!
    Again I had to comment out the “did we really connect to vCenter” check as it was assuming false over here even when it connected.
    Also, line #596… When run interactively I see an error: “Select-Object : The term ‘Get-VMHostNtpServer’ is not recognized as a cmdlet”… Process continues to work however. Am I just missing a function or is this a bug. How hard wold it be to sort the ESX Hosts in the “NTP Issues” report?
    Also, on the “VMs Removed” section… I have it set for default (i.e. 5 days), but it only shows the last 1 day worth of entries. Anyone else see this?

    Again, overall, simply very useful.

  102. Virtu-Al says:

    @Brandon Yap
    I will look into that one, do you have any vms on local storage ?

  103. Virtu-Al says:

    @Mark
    Sure, dop me a mail with the code, always intereasted in improvements !

    Thanks for your comments

  104. Brandon Yap says:

    I’m getting the following error:

    Get-VM : The argument cannot be null or empty.
    At C:\utils\DailyReportV2.ps1:588 char:36
    + $LocalVMs = @($LocalOnly | Get-VM <<<< | Where { $_.Name -notmatch $
    LVMDoNotInclude } |Get-View | Select Name, @{N="VMX";E={$_.Summary.Config.VmPat
    hName}})

    What does that mean?

  105. Mark says:

    Alan, Thanks for this wonderful work. I am new comer to vmware world and my first thing is to implement your script!. Now everyone thinks i am a genius! (due to your work). Thanks again. I worked on unix shell/perl a lot and always ignored powershell, but your script ignited me on powershell :-).

    I did bit of modification on your first script and adding the same to V2 now. Additions were minor and mainly the following:

    1) Passing email ID along with VIServer but both optional with default hardcoded
    2) It will add vmware snapin if not already loaded
    3) I also went crazy and included total runTime as it takes about 5 minutes in our environment (on the V1 script).

    Option 2 made easy for me to run via windows task schedular. If you think any value addition, i can send the code.

    Once again thank you.

  106. Virtu-Al says:

    @NiTRo
    Thanks man, and thanks for your previous comments and bug finding !

  107. NiTRo says:

    Alan, you really add great stuff in the V2 ! thanks again !

  108. Virtu-Al says:

    @Grasshopper
    Now we are getting to the hard stuff, I like it 😉 I will see what I can do.

  109. Grasshopper says:

    Would it be possible to include Update Manager information in the next version? Number of compliant and non-compliant updates on a host/VM level would be useful.

  110. Virtu-Al says:

    @DJLO
    Thanks for the great comments, I will look forward to the comission when you get the pay rise :)

  111. Virtu-Al says:

    @Rob P
    Im working on the coffee one at the moment but can only get tea :) thanks mate

  112. DJLO says:

    Alan,

    Wonderful work. My boss thinks i’m some kind of genius busting out all these reports !

    Seriously, your scripts have made my day to day job a whole lot more enjoyable

  113. Rob P says:

    Alan, you’ve done it again. It does everything except stir my coffee. Well done mate.

  114. Sven Huisman says:

    Great work again, Alan! Keep it up!

  1. August 25, 2009

    […] ever wonderful Virtu-Al has released an update to his PowerShell Daily report. This script is beyond awesome in usefulness and should be required in any production VI […]

  2. August 28, 2009

    […] Virtu-Al » PowerCLI: Daily Report V2 – Version two of a handy PowerShell based VMware Environment Daily Report from VMware vExpert and PowerShell guru Alan Renouf What’s new/Bug Fixes * Active VMs count * Inactive VMs count * DRS Migrations count and list * Correct NTP Server check for each host * VMs stored on local datastores * NTP Service check for each host * vmkernel warning messages for each host * VM CPU ready over x% […]

  3. September 1, 2009

    […] a quick look at how the day is going to be, before you get into the office. You can see his post here Comments [0]Digg […]

  4. September 3, 2009

    […] Daily Report September 3, 2009 Posted by Matt Roblin in Uncategorized. trackback http://www.virtu-al.net/2009/08/18/powercli-daily-report-v2/ Possibly related posts: (automatically generated)Justin Broadrick Gives Some Details on the Alan […]

  5. October 12, 2009

    […] The script are based on Alan Renouf`s Daily Report script for PowerCLI. […]

  6. April 12, 2010

    […] can use PowerCLI to report on the status of guests and hosts. Check out Alan Renouf’s excellent PowerCLI Daily Report, for a really good example of how far you can […]

  7. February 19, 2011

    […] you are using my Daily Report script and want a nice output I have just received a cool tip from NiTRo over at […]

  8. December 27, 2012

    […] CPU Ready – http://www.virtu-al.net/2009/08/18/powercli-daily-report-v2/ […]

Leave a Reply

%d bloggers like this: